Zeiger in Containern der STL
-
Bin noch nicht so bewandert, was die STL angeht.
Deswegen dachte ich bis eben, dass ich in einer Verwaltungsklasse einen Container mit Zeigern auf Objekte benutze. So etwa:
class Verwaltung { public: Verwaltung(); ~Verwaltung(); private: vector<BeliebigesObjekt*>* warteschlange; };Doch nun lese ich in einem C/C++ Kompendium:
C/C++ Kompendium schrieb:
Legen Sie in Containern keine Zeiger als Elemente ab. Die Container verschieben und kopieren Elemente, was bei Zeigerelementen zu Fehlern führen kann.
Muss ich meine Zeiger jetzt doch wieder in dynamisch allokierten Arrays verwalten? Könnte mir dass mal jemand näher erläutern?
-
DarthZiu schrieb:
Doch nun lese ich in einem C/C++ Kompendium:
C/C++ Kompendium schrieb:
Legen Sie in Containern keine Zeiger als Elemente ab. Die Container verschieben und kopieren Elemente, was bei Zeigerelementen zu Fehlern führen kann.
Muss ich meine Zeiger jetzt doch wieder in dynamisch allokierten Arrays verwalten? Könnte mir dass mal jemand näher erläutern?
Nö, du kannst einfach die boost Pointer-Container benutzen

Ansonsten wären auch Smart-Pointer ne Möglichkeit, findet man auch in der boost-lib. Der std::auto_ptr ist übrigens für dein Anliegen nicht geeignet.MfG
GPC
-
Ich würde mal sagen die Aussage in dem Kompendium ist ziemlicher Quatsch. Klar ist es nicht anzuraten, da man sich selbst um die Verwaltung der Objekte kümmern muss, aber z.B. bei Polymorphie geht es nicht anders, wenn man keine eigenen (oder boost) Container verwenden will/kann.
Und wenn ein Vektor von Zeigern Elemente kopiert oder verschiebt, werden Zeiger kopiert oder verschoben, da ist nichts fehleranfälliges dran zu erkennen. Will heissen, ein Zeigertyp hat einen gültigen Copy-Constructor, Zuweisungsoperator und Vergleichsoperatoren. Fertig.
-
DarthZiu schrieb:
C/C++ Kompendium schrieb:
Legen Sie in Containern keine Zeiger als Elemente ab. Die Container verschieben und kopieren Elemente, was bei Zeigerelementen zu Fehlern führen kann.
Muss ich meine Zeiger jetzt doch wieder in dynamisch allokierten Arrays verwalten? Könnte mir dass mal jemand näher erläutern?
die aussage ist zu allgemein und unspezifisch.
- die einzigen container, die das tun, sind vector und deque (und adapter darauf); zeiger auf elemente von list bleiben dagegen fast immer unter allen operationen gültig (und die wenigen fälle, wenn das nicht der fall ist, werden sehr widersprüchlich bewertet - es gibt da diskrepanzen zwischen dem wortlaut des standards und den äußerungen einiger komiteemitglieder bzgl. einiger defekt-reporte).
- es wird nicht gesagt, was für fehler gemeint sind: wenn sich objekte in einem der genannten container befinden, so werden zeiger darauf u.U. durch bestimmte operationen ungültig. umgekehrt spielt es aber keine rolle, in welcher art von container sich die zeiger befinden.
prinzipiell ist immer zunächst einmal die frage zu beantworten, warum überhaupt mit zeigern und nicht mit den objekten selbst gearbeitet wird. schließlich müssen die objekte selbst ja auch irgendwo existieren.
werden zeiger benötigt, um polymorphe objekte zu erhalten, so bieten sich boosts pointer container an. benötigt man andere indizierungen in einen container, kann man ebenfalls pointer_container einsetzen - das hat allerdings dann nur relativ geringfügige syntaktische vorteile. eleganter und effizienter ist hier die benutzung des multi index containers.
-
Oder wenn die Objekte sich nicht kopieren lassen gehts ja auch nicht anders.
-
Also Container, die Zeiger enthalten, sind im keine Seltenheit (das passiert z.B., wenn jemand polymorphe Objekte stapeln will). Das Problem ist die andere Seite: Zeiger auf Vektor-Elemente können ungültig werden, wenn du etwas mit dem Container machst (beim vector bei jedem insert() und erase() hinter der Zielposition sowie bei Reallokation überall, in einer deque bei einem insert()/erase() (je nach Postion für die vorderen oder hinteren Elemente), bei list, set's und map's betrifft es nur die Elemente, die direkt von der Operation betroffen sind).
-
Mal schauen, ob ich das richtig verstanden habe:
Zeiger auf Container ist schlecht, aber wenn ich den Container als Objekt habe und darin Zeiger auf Objekte ablege, ist das okay!?
-
Wo ist von Zeigern auf Container die Rede?
vector<int>* my_vector; // würde mir kein sinnvoller Zweck für einfallen vector<poly_base*> my_vector; // der name sagt's denke ich vector<poly_base*>::iterator it = my_vector.begin(); // it kann ungültig werden, gilt aber für vector<non_pointer> genauso!?
-
Ja, das sieht so richtig aus. Wobei - ein vector<T>* ist auch noch kein Problem, schwierig wird es erst, wenn du in den Container zeigst:
vector<int> data(5); int* pd0 = &data[0];//noch OK - zeigt auf den Anfang der Vektor-Daten data.push_back(7); //mögliches Problem: Reallocation -> pd0 zeigt auf freigegebenen Speicher