"delete" Frage
-
Ok danke, hab ichs mir doch richtig vorgestellt.
-
std::vector<std::auto_ptr<Kontobewegung> > bewegungen;Wenn ich das so gestalte(deklaration scheint noch fehlerhaft zu sein, da ich fehler bekomme) brauche ich mich später nicht über das aufräumem kümmern richtig`?
-
Theoretisch hast du da recht!
-
Firefighter schrieb:
Wenn ich das so gestalte(deklaration scheint noch fehlerhaft zu sein, da ich fehler bekomme) brauche ich mich später nicht über das aufräumem kümmern richtig`?
Falsch. auto_ptr ist wegen seiner Kopiersemantik nicht für die Container der Standardbibliothek geeignet.
-
EDIT: Ok MFK ich danke dir, das erklärt einige Fehler.
Mit den shared_ptr, hab ich recht? aber mal ne andere Frage, wenn meine deklaration wie oben aussieht, wie könnte dann ein pushback eines möglichen kontobewegung-zeiger aussehen?Die Referenz ist mir dabei gerade nicht sehr hilfreich

-
Kontenbewegung *bestechung = new Kontenbewegung(); bewegungen.push_back(bestechung);
-
Öhmm...nee ich glaube das meinte ich nicht...sondern ich meinte eher, wie es mit shared_ptr ausehen müsste?Weil mit den burschen hab ich noch net so viel erfahrung.
-
So?
bewegungen.push_back( shared_ptr<Kontenbewegung>( new Kontenbewegung() ) );
-
Ok das hilft mir schonmal weiter, und die Deklaration vom vector wäre dann so hier?:
std::vector< shared_ptr<Irgendwas> > vieles_irgendwas;?
-
Sieht ok aus.
-
Und auf die deklaration kann ich dein push_back anwenden? Kann doch eigentlich bei deinem push_back das führende shared<> zeugs weglassen und nur ein normales new machen oder nicht?
-
OK hat sich erledigt, habs alleine hinbekommen. Aber mal ne andere Frage, worin besteht nun der Underschied zwischen auto_ptr und shared_ptr?also aufjedenfall schonmal die Containerkompatiblität, und das shared_ptr sich ums aufräumen kümmert, aber was noch?
-
Ok hab mir auch das ebend selbst beantwortet, danke für eure Beiträge.
-
Vielleicht kannst du dir auch mal Boost.Pointer Container anschauen, da werden die Zeiger auch automatisch freigegeben.
-
Alles klar Nexus, danke für den Hinweis, kannste eventuell kurz erklären wo der signifikanteste Unterschied liegt?
-
Die Pointer-Container speichern intern gerade Zeiger (wie könnte es anders sein ;)). Es existieren die analogen Container zur STL, wie
ptr_vector,ptr_deque,ptr_listetc.Das führt zu verschiedenen Vorteilen für den Anwender:
- Die gespeicherten Elemente müssen im Gegensatz zu STL-Containern nicht kopierkonstruierbar oder zuweisbar sein.
- Bei Array-Containern wie
boost::ptr_vectorsind interne Operationen wie Löschungen und Einfügungen performanter, da nur Zeiger umgehängt werden. - Die Indirektion entfällt beim Aufruf. Man kann direkt schreiben
vec[1]odervec.front(), anstatt dass man noch einmal dereferenzieren muss.
Siehe auch hier.
P.S. Die ersten beiden Punkte beziehen sich auf den Vergleich zu STL-Containern mit Objekten, der dritte zu STL-Containern mit Smart-Pointern.
-
Klasse, ich danke, das sind ja fabelhafte Geschichten.Haste super erklärt.
-
David_pb schrieb:
So?
bewegungen.push_back( shared_ptr<Kontenbewegung>( new Kontenbewegung() ) );Das ist schlecht. Besser so:
shared_ptr<Kontenbewegung> kbw(new Kontenbewegung()); bewegungen.push_back(kbw);Begründung bitte selbst in der Boost Doku nachlesen, danke.
-
Danke hustbaer, habs mir mal durchgelesen.Mir ist aber noch nicht ganz klar was das im Bezug auf mein Konstrukt ausmacht.Ich hab mir mal das Beispiel aus der Boost Doku durchgelesen:
void f(shared_ptr<int>, int); int g(); void ok() { shared_ptr<int> p(new int(2)); f(p, g()); } void bad() { f(shared_ptr<int>(new int(2)), g()); }Wenn ich das also richtig verstanden habe:
Since function arguments are evaluated in unspecified order, it is possible for new int(2) to be evaluated first, g() second, and we may never get to the shared_ptr constructor if g throws an exception
Das Funktionsargumente in keiner bestimmten Reihenfolge abgearbeitet werden können, und im Falle einer Exception wir niemals bei dem eigentlichen shared_ptr Konstrukt ankommen, ist das so richtig?Was bedeutet das aber in meinem Fall?
bewegungen.push_back( shared_ptr<Kontenbewegung>( new Kontenbewegung() ) );Achso, es könnte also sein, das bei meiner erzeugung durch new eine Exception fliegt und ich dadurch nie bei shared_ptr ankomme?
-
wenn beim new eine Exception fliegt kann das aus zwei Gründen geschehen:
-
Fehler bei der Speicherallokation. Der Konstruktor des Objektes wird daher nie aufgerufen, alles paletti (außer dass du ohne Speicher schlecht dastehst)
-
Fehler im Ctor, dann werden die bereits konstruierten Teilobjekte wieder zerstört, die Exception fliegt und auch wieder kein Speicherleck - vorausgesetzt der Ctor ist exceptionsicher implementiert.
Du kriegst durch ne Exception beim new also keine Speicherlecks
Von der Exceptionsicherheit her kann man es also eigentlich als Einzeiler machen, wenns sich nur um einparametrige Funktionen handelt. Ob man sich das angewöhnen sollte und dann bei mehrparametrigen Funktionen immer dran denkt, es anders zu machen ist denke ich Geschmackssache. wirklich konsistent wäre es aber wohl nicht.
-