std::stack Objekt raus-moven
std::stack Objekt raus-moven
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?
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?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
-
- Beiträge: 75
- Registriert: 24.07.2002, 00:00
- Wohnort: Bremen
- Kontaktdaten:
Re: std::stack Objekt raus-moven
Spricht irgendetwas gegen ? Damit wird dein top zu einem leeren unique_ptr, der danach weggeräumt wird...
Code: Alles auswählen
auto top_element(std::move(stack.top())); stack.pop();
Re: std::stack Objekt raus-moven
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?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Schrompf
- Moderator
- Beiträge: 5047
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: std::stack Objekt raus-moven
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.
Hier im Fall des std::unique_ptr wird der Instanzzeiger des Ptrs im Stack wahrscheinlich auf null gesetzt.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: std::stack Objekt raus-moven
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
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: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 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:Der unique_ptr muss das ja irgendwie wissen, weil er sonst bei stack::pop das Objekt trotzdem löschen würde?
Die meisten gemoveten Objekte, welche tatsächlich Resourcen allokieren, haben so einen.Jonathan hat geschrieben:Aber es hat doch nicht jedes movebare Objekt einen "moved" Zustand?
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.
-
- Beiträge: 75
- Registriert: 24.07.2002, 00:00
- Wohnort: Bremen
- Kontaktdaten:
Re: std::stack Objekt raus-moven
@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.
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: std::stack Objekt raus-moven
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
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
http://www.cprogramming.com/c++11/rvalu ... c++11.html
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: std::stack Objekt raus-moven
Imo die zwei wesentlichen Links zu dem Thema:
http://thbecker.net/articles/rvalue_ref ... on_01.html
http://cpp-next.com/archive/2009/08/wan ... -by-value/
http://thbecker.net/articles/rvalue_ref ... on_01.html
http://cpp-next.com/archive/2009/08/wan ... -by-value/