C++ list, vektor aus der STL library

TVE

Erfahrenes Mitglied
Hi zusammen

Ich habe in meinem aktuellen Projekt mehrere Klassen von denen ich X Instanzen erstellen möchte. Da X unbekannt ist und ich sicher gehen will, dass bei jedem cycle im Programm alle vorhandenen Instanzen angesprochen werden kam ich erst auf die Idee einfach genug grosse Arrays (grösse Y) von der entsprechenden Klasse zu instanzieren. Dies ist aber erstens sehr Speicherlastig und zweitens habe ich dann das Problem, dass wenn ich mal Y+2 Instanzen benötigen sollte, das Programm natürlich abstürzt. (out of bounds, etc...)

Ein Freund hat mir darum geraten mich mit der STL auseinanderzusetzen und die Instanzen in eine list (oder auch einen vektor) zu packen, resp. einen Pointer auf die jeweilige Instanz. Ich hab da aber gar keine Erfahrung mit dem Teil und bin immer noch ein bisschen am Ausprobieren. Ein wirklich gutes Beispiel habe ich dazu auch noch nicht gefunden. Hat jemand gerade ein Idiot-Proof (If I read it, it prooves that I'm an idiot...) Tutorial zu dem Thema zur Hand?

Irgendwie habe ich Angst, dass wenn ich irgendwo im Code eine Instanz der Klasse erstelle, danach den Pointer in die list werfe, irgendwann später noch ein paar Pointer mehr reinknalle und dann das Programm beende Memory-Leaks entstehen. Mir ist noch keine Idee gekommen wie ich das verhindern kann; oder muss ich das gar nicht, weil die Destruktoren sowieso aufgerufen werden?

Ich weiss, ganz n Haufen Fragen. Ich hoffe jemand hat ein paar gute Antworten.
 
Du kannst mit new eine Instanz der Klasse erzeugen und den damit erhaltenen Zeiger mit push_back an Deinen Vektor oder die Liste anhängen. Die Definition der Vektor- bzw. Listenvariablen siehr folgendermaßen aus:
Code:
#include <list>
std::list<CMeineKlasse*> listMyClass;
bzw.
Code:
#include <vector>
std::vector<CMeineKlasseÜ> vectorMyClass;
bevor Du das Programm beendest, gehst Du die Liste oder den Vektor durch und rufst für jedes Element 'delete' auf:
Code:
//Iterator erzeugen und auf den Anfang der Liste zeigen lassen
std::list<CMeineKlasse*>::iterator itMyClass = listMyClass.begin();
//solange nicht das Ende der Liste erreicht ist ...
//(Beachte: end() liefert einen Iterator, der hinter das letzte Element des Containers
//zeigt, also auf ein ungültiges Element)
while(itMyClass != listMyClass.end())
{
    //Wenn das, worauf der Iterator zeigt nicht NULL ist, 'delete' aufrufen
    if((*itMyClass) != NULL)
        delete (*itMyClass);
    //Iterator auf nächstes Element
    itMyClass++;
}
Noch ein Hinweis: Ein Iterator ist kein Zeiger, auch wenn er teilweise wie einer verwendet wird.
 
Hallo jockey2

Danke erstmals für den Beispielcode und die Erläuterung dazu.

Ist irgendwie alles etwa so wie ich mir das auch vorgestellt habe... (ich traue mir selbst wohl nicht so ganz :) )

Eine Frage hätte ich trotzdem noch. Du erwähnst, dass ich meine Objekte mittels "new" instanzieren soll; ist das richtig, dass es sich dann um ein Heap-Objekt handelt? Momentan ist es nämlich so, dass meine Klassen keinen Rückgabewert beim Konstruktor haben, da ich die Instanzen bisher auch einfach so:
Code:
ClassX myClass;
erstellt habe. (also sprich im Memory auf den Stack geworfen wird)

Könnte ich auf eine solch erzeugte Instanz nicht mehr von überall her zugreifen? Ich bin mir mit den verschiedenen Arten von Memory-Handling nicht so vertraut. Falls nein, muss ich wohl meine Klassen bei den Konstruktoren abändern, wie?

Danke im Voraus! (und sorry die doofen Fragen, aber ich bin im Beruf ein Oracle-Fritze... C++ mach ich nur so nebenher...)
 
1. In C++ haben Konstruktoren und Destruktoren prinzipiell keinen Rückgabewert!!

2. Wenn Du auf Deine Weise eine Instanz einer Klasse erzeugst, wird sie tatsächlich auf dem Stack erzeugt, und zwar auf dem Stack des aktuellen Blocks (= alles, was innerhalb von geschweiften Klammern steht). beim Verlassen des Blocks werden die darin erzeugten Objekte automatisch aufgeräumt (d.h. der Destruktor wird aufgerufen und das Objekt gelöscht). Wenn Du also irgendwo noch einen Zeiger auf das Objekt hast, dann ist der ungültig und beim Zugriff darauf kracht es dann (Dein Programm stürzt ab).
Wenn Du eine Instanz mit 'new' anlegst, dann wird das Objekt auf dem Heap angelegt und 'new' liefert Dir einen Zeiger darauf. Dann bist Du aber auch dafür verantwortlich, das Objekt mit 'delete' wieder zu löschen, wenn es nicht mehr gebraucht wird.

Isses jetzt etwas klarer?
 
Ah genau was ich gebraucht habe! :)

Danke für die Klarstellung!

Also Konstruktoren NICHT anpassen, dafür aber auf den Heap packen.
 
Zurück