Destruktor
-
Guten Tag zusammen,
ich habe ein Tamplate programmiert.
Ich rufe eine Funktion auf, die eine Instanz der Klasse übergeben bekommt, z.B. m_equal.
Wenn die Funktion ausgeführt wurde, wird der Destruktor der übergebenen Instanz aufgerufen.
Warum ruft der den Destructor auf und zerstört damit das Array der anderen Instanz? Wie kann ich das verhindern? Ich will das Array erhalten.Der Rest soll so sein wie er ist.
Vielen Dank für die Hilfe.
template <class T> class C_Matrix { private: T *m_array; int m_r; int m_c; int m_elements; public: C_Matrix(int r, int c); ~C_Matrix(); int m_getRow(); int m_getColumn(); void m_getElement(); void m_setElement(); void m_transpose(); void m_equal(C_Matrix dummy); void m_add(C_Matrix dummy); void m_sub(C_Matrix dummy); void m_skalar(); void m_neg(); void m_multi(C_Matrix dummy); friend ostream& operator<< <> (ostream& os, C_Matrix<T>& dummy); friend istream& operator>> <> (istream& is, C_Matrix<T>& dummy); };Konstruktor/Destruktor
template <class T> C_Matrix<T>::C_Matrix(int r, int c) { int g; g = (r * c); m_array = NULL; m_array = new T[g]; if (m_array == NULL) throw "Fehler beim Erzeugen des Arrays"; for(int i = 0; i < g; i++) { m_array[i] = 0; } m_r = r; m_c = c; m_elements = r*c; } template <class T> C_Matrix<T>::~C_Matrix() { delete[] m_array; m_array = NULL; }m_equal
template <class T> void C_Matrix<T>::m_equal(C_Matrix dummy) { int i = 0; int j = 0; int z; if (m_r == dummy.m_r && m_c == dummy.m_c) { do { do { z = j + m_c*i; if (m_array[z] != dummy.m_array[z]) { cout << "Die " << i+1 << "," << j+1 << " Elemente sind unterschiedlich!" << endl; cout << "Die Matrizen sind nicht gleich.\n"; break; } if (m_array[z] != dummy.m_array[z]) break; j++; }while(j < m_c); if (m_array[z] != dummy.m_array[z]) break; i++; }while (i < m_r); if (m_array[z] == dummy.m_array[z]) cout << "Die Matrizen sind gleich!\n"; } }
-
Es fehlt der Kopierkonstruktor (und der Zuweisungsoperator). Die müssen natürlich eigenen Speichern anfordern und nicht nur der Zeiger auf das Array eines anderen Objektes übernehmen. Außerdem sollten Objekte per Referenz übergeben werden (das würde das Problem in diesem Fall auch umgehen).
-
Der Autor dieser Nachricht hat Probleme in Deinem Code identifiziert,
möchte sich aber durch dieses Antwortmuster Zeit sparen. Die für Dich
zutreffenden Tipps sind angekreuzt:
C++ behandelt Typen wie "int" und einen Klassentyp gleich (konsistent).
Im Gegensatz dazu bieten andere Sprachen wie Java und D "Referenzsemantik"
für Klassentypen.MeineMatrix m = new MeineMatrix(); MeineMatrix k = m; // m und k sind Referenzen, // die auf dasselbe Objekt zeigenMeineMatrix m (3,3); MeineMatrix k = m; // m und k sind zwei MeineMatrix-Objekte. // k ist eine Kopie von m.Gruß,
SP
-
der fehler liegt - wie schon gesagt - daran, dass du keinen op= und copy ctor hast - nun aber ein paar sätze zu deinem code an sich:
template <class T> class C_Matrix { private: T *m_array; int m_r; int m_c; int m_elements;m_r und m_c sind ein wenig komische bezeichner, meinst du nicht auch, ein paar mehr zeichen würden nicht schaden?!
public: C_Matrix(int r, int c);ich als nutzer wäre hier auch wieder ein wenig über r und c verwundert - würde zwar iwann mitbekommen, wofür es steht, aber auch hier wärs kein fehler bezeichner auszuschreiben...
~C_Matrix(); int m_getRow(); int m_getColumn();Getter sollten const sein (siehe "const correctness")
void m_getElement(); void m_setElement(); void m_transpose();wieso stellst du denn allen fkt ein m_ vor? hast du das schon mal irgendwo anders gesehen? ich kenn es nur bei member-variablen - und dort mag ich es zwar nicht, aber es gibt leute, die das bevorzugen...
void m_equal(C_Matrix dummy); void m_add(C_Matrix dummy); void m_sub(C_Matrix dummy); void m_skalar(); void m_neg(); void m_multi(C_Matrix dummy);dafür gibt es operatoren
siehe auch die artikel von pumuckl:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-232010.html
http://www.c-plusplus.net/forum/viewtopic-var-t-is-240706.html
http://www.c-plusplus.net/forum/viewtopic-var-t-is-242944.htmlfriend ostream& operator<< <> (ostream& os, C_Matrix<T>& dummy); friend istream& operator>> <> (istream& is, C_Matrix<T>& dummy); };1. weiß ich nicht, was du mit dem <> willst
2. brauchst du - da du es als friend in der klassendefinition geschrieben hast - nicht C_Matrix<T> sondern nur C_Matrix zu schreiben
3. außerdem hast du auch hier wieder nicht gekennzeichnet, dass die reference const ist - also beim op<<. siehe wieder const correctness
4. hast du wahrscheinlich einusing namespace std;im header - sollte man nicht tun!Konstruktor/Destruktor
template <class T> C_Matrix<T>::C_Matrix(int r, int c) { int g; g = (r * c);g ist wieder nen doofer bezeichner, zweitens würde es auch ein
int g = r*c;und du hättest statt 3 zeilen einem_array = NULL; m_array = new T[g];die erste zeile is sinnlos...
if (m_array == NULL) throw "Fehler beim Erzeugen des Arrays";1. sollte man auch die exception-klassen nutzen, wenn man fehler wirft und nciht einfach mit pointern um sich schmeißen...
2. wird das niemals geworfen!
new/new[] gibt entweder eine (gültige) adresse wieder oder wirft selbst ne exception(std::bad_alloc) - es gibt dann noch nen nothrow-new - wüsste aber nicht, welche vorteile das haben sollte...for(int i = 0; i < g; i++) { m_array[i] = 0; }ist ok
m_r = r; m_c = c; m_elements = r*c; }für so etwas nutzt man idR die Initialisierungsliste
template <class T> C_Matrix<T>::~C_Matrix() { delete[] m_array; m_array = NULL; }wieso genau setzt du m_array noch mal auf 0 - das objekt ist hier schon nicht mehr gültig - ist also einfach nur sinnlos ^^
m_equal
template <class T> void C_Matrix<T>::m_equal(C_Matrix dummy)wieso dummy? normalerweise nimmt man so etwas wie rhs oder other - aber dummy ist ja gerad nen name, der extrem verwirrt...
{ int i = 0; int j = 0; int z; if (m_r == dummy.m_r && m_c == dummy.m_c) { do { do { z = j + m_c*i; if (m_array[z] != dummy.m_array[z]) { cout << "Die " << i+1 << "," << j+1 << " Elemente sind unterschiedlich!" << endl; cout << "Die Matrizen sind nicht gleich.\n"; break; } if (m_array[z] != dummy.m_array[z]) break; j++; }while(j < m_c); if (m_array[z] != dummy.m_array[z]) break; i++; }while (i < m_r); if (m_array[z] == dummy.m_array[z]) cout << "Die Matrizen sind gleich!\n"; } }sry, aber das is mir zu grässlich -.-
außerdem sollte man niemals die ausgabe mit in fkt schmeißen, wo sie unintuitiv ist...
wenn du schon die genaue position wissen willst, an der die elemente unterschiedlich sind, gib halt nen zahlenpaar(die koordinaten) zurück...
dann kann der aufrufer selbst entscheiden, was er ausgibt und was nicht...bb