Anhand der von Ihnen verwendeten Terminologie und des dargestellten Codes ist schwer zu erkennen, was genau vor sich geht. Vielleicht würden Ihnen ein paar Beispiele weiterhelfen.
Array neu und Array löschen
Was ist los mit new []
y delete []
fragen Sie? Diese Typen werden für die Zuweisung/Deallokation von Arrays von Dingen verwendet. Diese Dinge können PODs oder vollwertige Objekte sein. Bei Objekten rufen sie den Konstruktor nach der Zuweisung und den Destruktor beim Deallokieren auf.
Nehmen wir ein erfundenes Beispiel:
class MrObject
{
public:
MrObject() : myName(new char[9]) { memcpy(myName, "MrObject", 9); }
virtual ~MrObject() { std::cout << "Goodbye cruel world!\n"; delete [] myName; }
private:
char* myName;
};
Jetzt können wir einige lustige Dinge mit MrObject machen.
Arrays von Objekten
Lassen Sie uns zunächst ein einfaches Array erstellen:
MrObject* an_array = new MrObject[5];
Damit haben wir ein Array von 5 MrObjects, die alle schön initialisiert sind. Wenn wir dieses Array löschen wollen, sollten wir ein Array delete ausführen, was wiederum den Destruktor für jedes MrObject aufruft. Versuchen wir das mal:
delete [] an_array;
Was aber, wenn wir es vermasseln und einfach eine normale Löschung vornehmen? Jetzt ist ein guter Zeitpunkt, es selbst zu versuchen
delete an_array;
Sie werden sehen, dass nur der erste Destruktor aufgerufen wird. Das liegt daran, dass wir nicht das gesamte Array gelöscht haben, sondern nur den ersten Eintrag.
Nun ja, manchmal. Es ist wirklich undefiniert, was hier passiert. Die Schlussfolgerung ist, die Array-Form von delete zu verwenden, wenn Sie ein Array new verwenden, dito für einfaches altes new und delete.
Vektoren von Objekten
OK, das hat Spaß gemacht. Aber lassen Sie uns jetzt einen Blick auf den std::vector werfen. Sie werden feststellen, dass dieser Kerl den Speicher für Sie verwaltet, und wenn er den Gültigkeitsbereich verlässt, wird alles, was er festhält, ebenfalls gelöscht. Lassen Sie uns eine Testfahrt mit ihm machen:
std::vector<MrObject> a_vector(5);
Jetzt haben Sie einen Vektor mit 5 initialisierten MrObjects. Schauen wir mal, was passiert, wenn wir das Ding löschen:
a_vector.clear();
Sie werden feststellen, dass alle 5 Zerstörer getroffen wurden.
Vektoren von Zeigern auf Objekte
Oooooh, sagst du, jetzt werden wir aber schick. Ich möchte alle Vorzüge von std::vector nutzen, aber ich möchte auch den gesamten Speicher selbst verwalten! Nun, auch dafür gibt es eine Zeile:
std::vector<MrObject*> a_vector_of_pointers(5);
for (size_t idx = 0; idx < 5; idx++) {
// note: it's just a regular new here, not an arra
a_vector_of_pointers[idx] = new MrObject;
}
Das war schon etwas mühsamer. Aber es kann nützlich sein, Sie könnten einen Nicht-Standard-Konstruktor beim Erstellen von MrObject verwenden. Du könntest stattdessen abgeleitete MrObjects dort hineinstellen. Nun, wie Sie sehen können, sind dem Himmel keine Grenzen gesetzt. Aber halt! Sie haben diesen Speicher angelegt, also sollten Sie ihn auch verwalten. Sie sollten eine Schleife über jeden Eintrag im Vektor laufen lassen und danach selbst aufräumen:
for (size_t idx = 0; idx < a_vector_of_pointers.size(); idx++) {
delete a_vector_of_pointers[idx];
}