Seite 1 von 1
std::stack Objekt raus-moven
Verfasst: 30.11.2012, 15:11
von Jonathan
Ich habe einen Stack der Objekte speichert, bislang mittels std::unique_ptr, weil ich mir keine Gedanken darüber machen wollte, wie ich meine Klasse movebar machen kann.
Jetzt muss ich allerdings ein Objekt aus dem Stack entfernen, damit aber noch weiter arbeiten können. stack::pop liefert aber kein Objekt zurück, und mit stack::top bekomme ich nur eine Referenz auf das oberste, d.h. ich müsste das Objekt kopieren, was mit einem unique_ptr ja nicht geht und was auch gar nicht passieren soll.
Wie bekomme ich jetzt ohne fiese Hacks mein Objekt aus dem Stack wieder raus?
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 15:23
von Florian Keßeler
Spricht irgendetwas gegen
Code: Alles auswählen
auto top_element(std::move(stack.top())); stack.pop();
? Damit wird dein top zu einem leeren unique_ptr, der danach weggeräumt wird...
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 15:49
von Jonathan
Ja, das sieht schonmal gut aus. Aber nur mal so fürs Verständnis: Was genau passiert jetzt mit dem gemoveten Objekte? Ich meine, vor dem stack.pop muss da ja noch irgendein Objekt rumliegen, nur in einem ungültigen Zustand, weil es woanders hin gemoved wurde? Der unique_ptr muss das ja irgendwie wissen, weil er sonst bei stack::pop das Objekt trotzdem löschen würde? Aber es hat doch nicht jedes movebare Objekt einen "moved" Zustand?
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 15:57
von Schrompf
std::move() benutzt den Move-Konstruktor der Klasse. Und die Move-Operation wird halt so implementiert, dass das Quell-Objekt in einen eindeutigen Null-Zustand zurückgesetzt wird. Das braucht Dir keine Sorgen zu machen, das ist Aufgabe der Klasse. Und wenn die Klasse behauptet, movable zu sein, kannst Du Dich darauf verlassen.
Hier im Fall des std::unique_ptr wird der Instanzzeiger des Ptrs im Stack wahrscheinlich auf null gesetzt.
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 16:00
von dot
Das unique_ptr move tut effektiv nichts andres als die Pointer der beiden beteiligten Objekte zu swappen. Im konkreten Fall wird also der Pointer aus dem Stack mit einem nullptr geswapped. Ergebnis davon ist, dass dein top_element nun den richtigen Pointer hat und der Pointer im Stack einen nullptr...
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 16:02
von eXile
Jonathan hat geschrieben:Ich meine, vor dem stack.pop muss da ja noch irgendein Objekt rumliegen, nur in einem ungültigen Zustand, weil es woanders hin gemoved wurde?
Das Original-Objekt wird durch den Move-Konstruktor in einen ungültigen Zustand versetzt. Den Move-Konstruktor musst du entsprechend so implementieren.
Jonathan hat geschrieben:Der unique_ptr muss das ja irgendwie wissen, weil er sonst bei stack::pop das Objekt trotzdem löschen würde?
Der Destruktor des Original-Objekts wird immer aufgerufen. Der Destruktor muss erkennen, dass
this auf ein ungültigen Objekt zeigt; das musst du so entsprechend implementieren.
Jonathan hat geschrieben:Aber es hat doch nicht jedes movebare Objekt einen "moved" Zustand?
Die meisten ge
moveten Objekte, welche tatsächlich Resourcen allokieren, haben so einen.
Als Standard-Beispiel siehe
hier, wo
_data == nullptr einen ungültigen Zustand anzeigt. Der Move-Konstruktor und Move-Assignment-Operator setzen diesen ungültigen Zustand beim Original-Objekt. Der Destruktor erkennt den ungültigen Zustand, und gibt keine Resourcen frei.
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 16:07
von Florian Keßeler
@dot: also zumindest in meiner libstdc++ ruft der Move-Konstruktor explizit release() des alten unique_ptrs auf und initialisiert den eigenen internen Zeiger mit dem Ergebnis. Swap wäre auch ein Extraschritt, weil der interne Zeiger des neu konstruierten Objekts erstmal mit nullptr initialisiert werden müsste.
Re: std::stack Objekt raus-moven
Verfasst: 30.11.2012, 16:17
von dot
Ich sagte, dass das "effektive" Verhalten einem Swap entspricht; ich meinte damit nicht, dass jede Implementierung intern zwangsweie std::swap aufrufen muss... ;)
Re: std::stack Objekt raus-moven
Verfasst: 16.03.2013, 00:08
von Jonathan
Ich habe mich gerade eben mit dem Thema etwas weiter auseinandergesetzt und fand folgenden Artikel sehr hilfreich für das tiefere Verständnis:
http://www.cprogramming.com/c++11/rvalu ... c++11.html
Re: std::stack Objekt raus-moven
Verfasst: 16.03.2013, 00:25
von dot