Kursinhalt
C++ Smart Pointers
C++ Smart Pointers
Aufbrechen von Zirkulären Referenzen mit Schwachen Pointern
Wie wir im vorherigen Abschnitt gesehen haben, treten zirkuläre Referenzen auf, wenn zwei (oder mehr) geteilte Zeiger sich gegenseitig in einer Schleife referenzieren, wodurch ein tödlicher Kreislauf entsteht. Diese Interdependenz verhindert, dass der Destruktor des Objekts aufgerufen wird, da die Referenzzähler niemals null erreichen. Das Ergebnis ist ein sehr häufiges Speicherleck, das der Hauptgrund für die Einführung von schwachen Zeigern wurde.
Den Kreislauf mit schwachen Zeigern durchbrechen
Schwache Zeiger sind speziell dafür entwickelt, diese Kreisläufe zu durchbrechen. Indem man einen geteilten Zeiger in einer zirkulären Referenz durch einen schwachen Zeiger ersetzt, kann man sicherstellen, dass eines der Objekte nicht künstlich die Lebensdauer eines anderen verlängert, was verhindern würde, dass eines von beiden zerstört wird.
Um dieses Konzept besser zu verstehen, lassen Sie uns das Problem der zirkulären Referenz in der verketteten Liste, das wir im vorherigen Abschnitt besprochen haben, mit einem schwachen Zeiger neu schreiben.
main
#include <iostream> #include <memory> class Node { public: // A weak pointer to the next element prevents circular ownership. std::weak_ptr<Node> next; // The constructor. Node() { std::cout << "Node constructed." << std::endl; } // The destructor. ~Node() { std::cout << "Node destructed." << std::endl; } }; int main() { // Creating three Node objects. std::shared_ptr<Node> node1 = std::make_shared<Node>(); std::shared_ptr<Node> node2 = std::make_shared<Node>(); std::shared_ptr<Node> node3 = std::make_shared<Node>(); // Creating a list where the last node's next is a weak pointer, // thus preventing a circular reference. node1->next = node2; node2->next = node3; node3->next = node1; // Now when node1, node2, and node3 go out of scope, their destructors will be called, // and the memory will be properly deallocated. }
Im obigen Code haben wir unser Problem mit der zirkulären Referenz gelöst, indem wir next
von einem geteilten Zeiger in einen schwachen Zeiger geändert haben. Folgen Sie den Kommentaren im obigen Code für ein besseres Verständnis. Und vergessen Sie nicht, den Code auszuführen, um zu sehen, dass die Destruktoren jetzt aufgerufen werden. Keine Speicherlecks!
Danke für Ihr Feedback!