unique_ptr, shared_ptr und weak_ptr
Ein Smart Pointer ist ein verwaltendes Objekt mit zeigerähnlichem Zugriff. Die Standardvarianten stehen in <memory>. Sie lösen Besitzfragen, aber nicht automatisch alle Lebensdauer-, Index- oder Nebenläufigkeitsfehler.
unique_ptr, shared_ptr und weak_ptr#
Referenzen, Zeiger und Speicher · Lektion 37 von 60
Voraussetzungen: RAII. Lernziel: Du drückst Besitz ausdrücklich aus und verhinderst Lecks durch geteilte Zuständigkeit.
Ein Smart Pointer ist ein verwaltendes Objekt mit zeigerähnlichem Zugriff. Die Standardvarianten stehen in <memory>. Sie lösen Besitzfragen, aber nicht automatisch alle Lebensdauer-, Index- oder Nebenläufigkeitsfehler.
1#include <iostream>2#include <memory>3#include <utility>4 5int main() {6 auto besitzer = std::make_unique<int>(42);7 std::cout << *besitzer << '\n';8 auto neuerBesitzer = std::move(besitzer);9 if (!besitzer) {10 std::cout << "Besitz wurde uebertragen.\n";11 }12 std::cout << *neuerBesitzer << '\n';13}std::unique_ptr hat exklusiven Besitz: Genau dieses Besitzerobjekt ist zuständig. std::make_unique erzeugt Objekt und Besitzer zusammen. Eine Kopie des Besitzers ist verboten. std::move erlaubt hier die Übertragung; danach ist der ursprüngliche unique_ptr leer. Die allgemeine Bedeutung von Move folgt in einer eigenen Lektion.
Geteilter Besitz#
std::shared_ptr verwendet Referenzzählung: Eine Verwaltungsstruktur zählt die beteiligten gemeinsamen Besitzer. Wenn der letzte besitzende shared_ptr verschwindet, wird das Ziel zerstört. Erzeuge solche Objekte gewöhnlich mit std::make_shared.
Geteilter Besitz kostet zusätzliche Verwaltung und kann die Verantwortlichkeit verschleiern. Nutze ihn, wenn mehrere unabhängige Stellen die Lebensdauer wirklich gemeinsam bestimmen müssen. Reines Mitlesen erfordert nicht automatisch einen neuen Besitzer.
Schwache Referenzen und Zyklen#
std::weak_ptr beobachtet eine geteilte Lebensdauer, ohne sie selbst zu verlängern. Mit lock() versuchst du einen gültigen shared_ptr zu erhalten; ein leeres Ergebnis bedeutet, dass das Objekt nicht mehr verfügbar ist.
Ein Besitzzyklus entsteht, wenn zwei Objekte sich gegenseitig über shared_ptr besitzen. Dann kann die Zählung auf beiden Seiten positiv bleiben, obwohl außen niemand mehr darauf zugreift. Eine passende Rückverbindung als weak_ptr kann den Zyklus aufbrechen.
Zugriff ist nicht Besitz#
get() liefert einen nichtbesitzenden Rohzeiger. Rufe dafür kein eigenes delete auf. release() gibt beim unique_ptr die Zuständigkeit ab, ohne das Objekt zu löschen; danach muss ein anderer Besitzer die Freigabe sicher übernehmen. Verwende es nicht als gewöhnliche Methode zum „Leermachen“; dafür gibt es reset().
Eine threadsichere Verwaltungszählung macht das gemeinsam gehaltene Zielobjekt nicht automatisch threadsicher. Gleichzeitige Änderungen brauchen eigene Synchronisation.
Übung#
Warum scheitert auto kopie = besitzer; bei einem unique_ptr?
Lösung
Es würde zwei exklusive Besitzer erzeugen. Der Typ verhindert Kopieren. Übertrage bei Bedarf ausdrücklich den Besitz oder gib zum reinen Benutzen eine passende Referenz weiter.
Weiterlernen#
Zurück: Dynamischer Speicher, new/delete und RAII · Kursübersicht · Weiter: Zusammengehörige Daten mit struct bündeln
Kommentare 0
Kommentare sind für diese Seite deaktiviert.