Einige Details der Klasse wurden entfernt. Insbesondere weist der Konstruktor das DataStructure
-Objekt dynamisch zu, und der Destruktor hebt es auf. Wenn Sie während einer Verschiebung den Zeiger von einem Widget
auf einen anderen kopiert haben, hätten beide Widget
s Zeiger auf dasselbe zugeordnete DataStructure
-Objekt. Wenn diese Objekte dann zerstört werden, versuchen sie beide delete
it. Dies würde zu undefiniertem Verhalten führen. Um dies zu vermeiden, wird für den Widget
, von dem verschoben wird, der interne Zeiger auf nullptr
gesetzt.
Dies ist ein Standardmuster bei der Implementierung eines Move-Konstruktors. Sie möchten das Eigentumsrecht für einige dynamisch zugewiesene Objekte von einem Objekt auf ein anderes übertragen. Sie müssen also sicherstellen, dass das ursprüngliche Objekt nicht mehr die zugeordneten Objekte besitzt.
Schematisch beginnen Sie mit dieser Situation, indem Sie den Besitz von DataStructure
von einem Widget
auf den anderen übertragen möchten:
Wenn Sie den Zeiger einfach kopiert haben, müssten Sie:
%Vor% Wenn Sie dann den ursprünglichen Widget
Zeiger auf nullptr
setzen, haben Sie:
Der Besitz wurde erfolgreich übertragen, und beide Widget
s können zerstört werden, ohne ein undefiniertes Verhalten zu verursachen.
Das DataStructure
-Objekt ist wahrscheinlich "Eigentum" von Widget
und das Zurücksetzen des Zeigers verhindert, dass es versehentlich gelöscht wird, wenn Widget
zerstört wird.
Alternativ ist es üblich, Objekte auf einen "leeren" oder "default" -Zustand zurückzusetzen, wenn sie verschoben werden, und das Zurücksetzen des Zeigers ist ein harmloser Weg, der Konvention zu folgen.
Ich habe einen Destruktor in der obigen Klasse hinzugefügt.
%Vor%Um zu veranschaulichen, was passieren würde, wenn Sie die Nullptr-Zuweisung entfernen, überprüfen Sie die obigen Methoden. Ein Widget a würde in einer Hilfsfunktion erstellt und dem Widget b zugewiesen werden.
Da das Widget a den Geltungsbereich verlässt, wird sein Destruktor aufgerufen, der den Speicher freigibt, und Sie bleiben mit dem Widget b zurück, das auf die ungültige Speicheradresse verweist.
Wenn Sie rhs Nullptr zuweisen, wird auch ein Destruktor aufgerufen, aber seit lösche nullptr tut nichts ist alles gut:)
Tags und Links c++ c++11 move-semantics rvalue-reference move-constructor