Problem mit shared Pointern
-
Ich habe eine Klasse Rabbit in dessen Konstruktor folgendes steht:
allRabbits.push_back(boost::shared_ptr<Rabbit>(this));dabei ist allRabbits eine std::List und static member von Rabbit.
In der main() habe ich dann das stehen:
boost::shared_ptr<Rabbit> myRabbit(new Rabbit());Und nach dem Beenden des Programms lande ich mit einer access violation in der checked_delete.hpp von boost.
Nach ein bischen überlegen ist mir aufgefallen, dass die beiden shared_ptr<Rabbit> voneinander nix wissen sollten, desshalb wird intern nicht richtig gezählt und das Objekt wird gelöscht und danach nochmal gelöscht(access violation). Stimmt das soweit?
Wenn ja wie löse ich das geschickt? Ich möchte quasi einen shared_ptr in der Main haben, auf dem 2 Referenzen(Main und allRabbits) sind.
-
Sich im Konstruktor einer Klasse irgendwo einzutragen halte ich für mehr als fragwürdig. Aber abgesehen davon solltest du dann auch rohe Pointer nutzen. Was ist denn wenn jemand einen Hasen auf dem Stack erstellt?
Edit: Am besten du beschreibst mal das gesamte Problem und was du erreichen möchtest, denn das da sieht so aus als sollte man das Design noch mal komplett überdenken.
-
JJ_ schrieb:
Nach ein bischen überlegen ist mir aufgefallen, dass die beiden shared_ptr<Rabbit> voneinander nix wissen sollten, desshalb wird intern nicht richtig gezählt und das Objekt wird gelöscht und danach nochmal gelöscht(access violation). Stimmt das soweit?
Korrekt. Für Fälle wie diese gibt es enable_shared_from_this, shared_ptr wird damit effektiv zu einem intrusive_ptr, so dass shared_ptr mehrfach vom gleichen rohen Zeiger erzeugt werden können.
-
Das ist glaube ich das, was ich gesucht habe, verstanden habe ich das aber nicht :/.
Also ich weis nicht wie die Syntax dazu ausehen soll, damit ich das bekomme was ich möchte...Ich erbe von enable_shared_from_this<Rabbit>... und dann?
Wo verwende ich das shared_from_this()?
-
Kuck dir mal das Beispiel in der boost-Doku an:
http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/enable_shared_from_this.html
-
Möglicherweise entfällt die Notwendigkeit zu
enable_shared_from_this(), wenn du dein Design ein wenig änderst. Ist es wirklich sinnvoll, dassRabbitallRabbitskennt? Wenn die Hasen nämlich autonom sind, kannst du denshared_ptrausserhalb der Klasse in die Liste einfügen und musst gar nie mitthishantieren.Ich selbst habe noch nie
enable_shared_from_this()benötigt, obwohl ich inzwischen ab und zu mitshared_ptrarbeite.
-
@XPille Ja, die doku hab ich mir schon angesehen. Allerdings habe ich das Problem das ich bereits im Konstruktor von Rabbit den ersten shared_ptr anlege und ich nicht drauf komme wie ich nun automatisch in der main() den zweiten shared_ptr auf den ersten biegen kann.
@Nexus Also Rabbit hat eine Member-Funktion Suicide(), welche - man kann es ahnen - den Hasen tötet. Mit dem ableben wird auch Rabbit aus allRabbits entfernt, deshalb hab ich mir gedacht es macht sinn das Rabbit allRabbits kennt.
Wenn ich die Liste ausserhalb führen würde müsste ich jedesmal beim erstellen eines Hasen diesen manuell in die Liste einfügen und beim ableben(was evtl. ausserhalb des Sichtsbereich der Liste geschieht) diesen wieder manuell entfernen, wenn ich das versäume, dann hab ich Schrödingers Hasen ;).
-
Ich habe es jetzt so geschrieben:
Rabbit.cpp
boost::shared_ptr<Rabbit> Rabbit::shared_ptr_from_RabbitList() { return shared_from_this(); }Main.cpp
boost::shared_ptr<Rabbit> myRabbit = (new Rabbit())->shared_ptr_from_RabbitList();Das sieht aber merkwürdig aus und geht bestimmt besser...