Skip to content

Latest commit

 

History

History
91 lines (63 loc) · 4.1 KB

File metadata and controls

91 lines (63 loc) · 4.1 KB

Smart Pointer Klassen

Zurück


Inhalt


Allgemeines

Smart Pointer in C++ verwalten den Lebenszyklus von Objekten auf dem Heap automatisch und verhindern Memory Leaks.

Das Problem mit dem elementaren new-Operator ist, dass der Aufruf des dazugehörigen delete-Operators fehlen kann. Der so reservierte Speicherbereich kann auf diese Weise nie mehr anderweitig vergeben werden.

Ein alternativer Ansatz

Folgende Überlegungen haben zu einem alternativen Ansatz geführt:

  • C++ ist eine objektorientierte Programmiersprache.
  • Folglich gibt es Klassen und Objekte.
  • Klassen/Objekte besitzen Konstruktoren und Destruktoren.
  • Wann wird speziell ein Destruktor aufgerufen: Am Ende des Scopes des zugehörigen Objekts.
  • Damit kann man sagen: Der Aufruf eines Destruktors ist deterministisch – im Gegensatz zum Aufruf des delete-Operators, der explizit vom Anwender abzusetzen ist.
  • Idee: Man platziere / verstecke den durch new erhaltenen Zeiger in einer Hüllenklasse / einem Hüllenobjekt (Wrapper-Objekt):
    • Konstruktor des Hüllenobjekts: Bekommt auf irgendeine Weise den Zeiger übergeben.
    • Destruktor des Hüllenobjekts: Aufruf von delete.

Diese Idee wurde in folgenden SmartPointer-Klassen umgesetzt, die unterschiedliche Strategien in der Verwaltung des nativen Zeigers verfolgen:

  • Klasse std::unique_ptr
  • Klasse std::shared_ptr
  • Klasse std::weak_ptr

Klasse std::unique_ptr – Exklusiver Besitz

Überblick über die Haupteigenschaften:

  • Konzept: Ein Objekt hat einen einzigen Besitzer.
  • Kopieren: Geht nicht (kein Kopierkonstruktor).
  • Wertzuweisung: Geht nicht (kein Zuweisungsoperator operator=).
  • Verschieben: Geht via std::move() – Besitzübergabe.
  • Performance: Schnell, kein Overhead gegenüber nativen Zeigern.
  • Lebensdauer: Das Objekt wird gelöscht, wenn das aktuell besitzende std::unique_ptr-Objekt zerstört wird.
  • Erzeugung: Bevorzugt mit std::make_unique<T>().

Klasse std::shared_ptr – Geteilter Besitz

  • Konzept: Ein Objekt hat mehrere Besitzer.
  • Kopieren: Geht (Kopierkonstruktor).
  • Wertzuweisung: Geht (Zuweisungsoperator operator=).
  • Mechanismus: Nutzt intern einen Referenzzähler (Reference Counting). Gewisse Ähnlichkeiten zu einem Garbage Collector sind vorhanden.
  • Lebensdauer: Das Objekt wird gelöscht, wenn das letzte besitzende std::shared_ptr-Objekt zerstört wird.
  • Performance: Etwas Overhead durch die Verwaltung des Referenzzählers (Threadsicher).
  • Erzeugung: Bevorzugt mit std::make_shared<T>().

Klasse std::weak_ptr – Temporärer Besitz

  • Konzept: Verweist auf ein Objekt, das von einem std::shared_ptr-Objekt verwaltet wird, ohne den Referenzzähler zu beeinflussen.
  • Hauptzweck: Ermöglicht Zugriff auf den von einem std::shared_ptr-Objekt verwalteten Speicherbereich, ohne einen Besitzanspruch zu verlangen. Es ist möglich, dass dieser Speicherbereich nicht mehr existiert.
  • Weiterer Zweck: Verhindert zyklische Referenzen (Memory Leaks, bei denen sich zwei Objekte gegenseitig referenzieren).
  • Zugriff: Kann nicht direkt auf die Daten zugreifen. Mit einem Aufruf von lock() wird temporär ein std::shared_ptr-Objekt zur Verfügung gestellt.
  • Prüfung: Eine Methode expired() prüft, ob das Objekt bereits gelöscht wurde.
  • Erzeugung: Durch Zuweisung eines std::shared_ptr-Objekts an ein std::weak_ptr-Objekt.

Weitere Details

Hier geht es zur vertiefenden Betrachtung der drei Hauptklassen:


Zurück