[Templates] Destruktor wird plötzlich aufgerufen
-
Hallo, ich hab hier eine eigene Array-Klasse mithilfe von einem Template geschrieben.
Jetzt hab ich nur folgendes Problem:
Eine Funktion ruft den Destruktor auf. Ich hab keine Ahnung wieso...Hier der Code:
Array.h
template<class ItemClass> class CUnSafeArray { public: //public methods //constructor CUnSafeArray(); CUnSafeArray(int buffer_size); CUnSafeArray(int size,ItemClass init_value); //destructor ~CUnSafeArray(); ItemClass& GetAt(int index){ return pArray[index]; } //UNSAFE ItemClass& operator[](int index) { return GetAt(index); } //UNSAFE void SetAll(ItemClass value) { int n; for(n=0;n<ArraySize;n++) pArray[n]=value; } bool Insert(ItemClass value, int index); //Inserts a new item at index UNSAFE bool InsertAtEnd(ItemClass value); bool Remove(int index); int Add(CUnSafeArray array, int index); //inserts array at index int Add(CUnSafeArray array); //adds array to the end of this array bool Resize(int new_size); int GetSize() { return ArraySize; } void Clear(); void ClearBuffer(); void QuickSort(int (__cdecl *compare )(const void *, const void *)); //compare(void* item1, void* item2) is a function that returns <0 if item1<item2, 0 if item1==item2, > if item1>item2 protected: //protected methods public: //public data /*none*/ protected: //protected data ItemClass* pArray; int ArraySize; int ArrayBufferSize; }; //For templates, the code hast to be in the header file //thats not a problem of C++, thats a problem of the compiler that does not support "export" //So we must include here the Array.cpp file :( #include "Array.cpp"Hier die Funktion, die den Destruktor aufruft:
template<class ItemClass> int CUnSafeArray<ItemClass>::Add(CUnSafeArray array, int index) //insert an array at the position index { /* int n,i; int old_array_size=ArraySize; int other_array_size=array.GetSize(); Resize(ArraySize + other_array_size); //WARNING ArraySize get's changed to the new size //copy elements of this array from index on to the end i=index+other_array_size; for(n=index;n<old_array_size;n++) { pArray[i]=pArray[n]; i++; } //insert elements of the other array i=index; for(n=0; n<other_array_size; n++) { pArray[i]=array.GetAt(n); i++; } */ return ArraySize; }Wie ihr seht hab ich das meiste ausgekommentiert um den Fehler einzugrenzen, aber das scheint nichts zu bewirken.
Wenn ich mit meinem Debugger am Ende der Funktion ankomme, wird der Destruktor aufgerufen. Dann kehrt die Funktion zurück. Und plötzlich springt das Programm wieder in den Destruktor. Der Array ist natürlich mit delete [] schon freigegeben worden -> CRASHNaja, hier auch nochmal main.cpp:
int main(int argc, char* argv[]) { int n; for(n=0;n<5;n++) test_array.InsertAtEnd(n); for(n=0;n<4;n++) add_array.InsertAtEnd(n+10); cout << "Anfang: " <<endl; PrintArray(test_array); cout <<endl; cout <<"Füge nun folgenden Array ein: " <<endl; PrintArray(add_array); cout <<"füge an position 2 ein..." <<endl; test_array.Add(test_array,2); // <- Funktion ruft komischerweise destruktor auf //nach ende wird nochmals destruktor aufgerufen PrintArray(add_array); system("PAUSE"); return 0; }
-
Du übergibst array "by value", also wird für den Funktionsaufruf eine Kopie angelegt, mit Hilfe des Copykonstruktors. Diese Kopie wird am Ende von Add wieder gelöscht -> Destruktoraufruf.
Du hast keinen Copykonstruktor definiert, also macht das der Compiler. Und der kopiert einfach nur jeden Member, auch den Zeiger.
Definier für deine Klasse einen ordentlichen Copykonstruktor und Copy-Zuweisungsoperator, dann geht's auch.
-
Jawoll, jetzt geht's, du hattest vollkommen Recht
.
Ich übergebe den Array jetzt als Referenz und nun funktionierts.So, ein anständiger Copykonstruktor muss aber trotzdem her

Danke für deine Hilfe!
-
Übringes auch ein Zuweisungsoperator, nicht dass du da dann in die nächste Falle tappst.
Ich glaub irgendeiner hier hatte das mal als "Dreierregel" oder sowas bezeichnet:
Wenn eine der drei Funktionen Kopierkonstruktor, Zuweisungsoperator oder Destruktor implementiert ist, so müssen auch die übrigen zwei implementiert werden.Du kannst auch sicherheitshalber, solange du keine der beiden Funktionen nutzen willst ihre Deklaration in den private-Block schreiben, das erspart dir derartige Fehler.
-
.filmor schrieb:
Ich glaub irgendeiner hier hatte das mal als "Dreierregel" oder sowas bezeichnet: