Menu
Coddy logo textTech

Smart Pointers in C++

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 15 von 104.

Smart Pointer sind Wrapper-Klassen, die den Heap-Speicher automatisch für Sie verwalten. Sie machen manuelle delete-Aufrufe überflüssig, indem sie den Speicher bereinigen, wenn der Pointer seinen Gültigkeitsbereich verlässt.

Binden Sie den <memory>-Header ein, um Smart Pointer zu verwenden.

unique_ptr - exklusives Eigentum. Nur ein Pointer kann die Ressource zu einem Zeitpunkt besitzen.

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Verwendung wie ein normaler Zeiger

// Kann nicht kopiert werden, aber der Besitz kann übertragen werden
std::unique_ptr<Player> player2 = std::move(player);
// player ist jetzt nullptr

shared_ptr - Gemeinsamer Besitz. Mehrere Pointer können dieselbe Ressource besitzen. Der Speicher wird freigegeben, wenn der letzte Besitzer zerstört wird.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Beide besitzen die Ressource

std::cout << p1.use_count();  // Gibt 2 aus

weak_ptr - nicht-besitzender Beobachter eines shared_ptr. Nützlich, um zirkuläre Referenzen aufzubrechen.

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // In shared_ptr umwandeln
    locked->attack();
}

Verwenden Sie standardmäßig unique_ptr für alleiniges Eigentum. Verwenden Sie shared_ptr, wenn mehrere Objekte eine Ressource gemeinsam nutzen müssen. Verwenden Sie weak_ptr, um zu beobachten, ohne die Lebensdauer zu verlängern.

Bevorzugen Sie make_unique und make_shared gegenüber einfachem new.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Dokumentenfreigabesystem erstellen, das die verschiedenen Eigentumsmodelle von Smart Pointern demonstriert. Sie werden sehen, wie unique_ptr exklusives Eigentum erzwingt, wie shared_ptr mehrere Eigentümer ermöglicht und wie weak_ptr beobachten kann, ohne die Lebensdauer zu beeinflussen.

Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:

  • Document.h: Definieren Sie eine Klasse Document, die ein freigebbares Dokument darstellt. Sie sollte Folgendes enthalten:
    • Ein privates Attribut title (String)
    • Einen Konstruktor, der einen Titel entgegennimmt und "Document created: <title>" ausgibt
    • Einen Destruktor, der "Document deleted: <title>" ausgibt
    • Eine Methode getTitle(), die den Titel zurückgibt
  • main.cpp: Demonstrieren Sie alle drei Smart-Pointer-Typen, indem Sie einen Dokumenttitel aus der Eingabe lesen und dann:
    • Einen unique_ptr auf ein Document mit dem eingegebenen Titel erstellen
    • "Unique owner: <title>" ausgeben
    • Das Eigentum mit std::move auf einen anderen unique_ptr übertragen
    • "Ownership transferred" ausgeben
    • Einen shared_ptr auf ein neues Document mit dem Titel "SharedDoc" erstellen
    • Einen zweiten shared_ptr erstellen, der auf dasselbe Dokument zeigt
    • "Shared owners: <count>" unter Verwendung von use_count() ausgeben
    • Einen weak_ptr von einem der Shared Pointer erstellen
    • lock() verwenden, um über den Weak Pointer auf das Dokument zuzugreifen und "Weak access: <title>" auszugeben

Denken Sie daran, <memory> für Smart Pointer einzubinden. Verwenden Sie std::make_unique und std::make_shared, um Ihre Smart Pointer zu erstellen. Die Destruktor-Meldungen helfen Ihnen zu sehen, wann jedes Dokument am Ende des Programms automatisch bereinigt wird.

Binden Sie Ihre Header-Datei in main.cpp mit #include "Document.h" ein.

Spickzettel

Smart Pointer sind Wrapper-Klassen, die den Heap-Speicher automatisch verwalten. Binden Sie den Header <memory> ein, um sie zu verwenden.

unique_ptr

Exklusiver Besitz – nur ein Pointer kann die Ressource gleichzeitig besitzen:

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Wie einen regulären Pointer verwenden

// Transfer ownership with std::move
std::unique_ptr<Player> player2 = std::move(player);
// player is now nullptr

shared_ptr

Geteilter Besitz – mehrere Pointer können dieselbe Ressource besitzen. Der Speicher wird freigegeben, wenn der letzte Besitzer zerstört wird:

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Beide besitzen die Ressource

std::cout << p1.use_count();  // Gibt 2 aus

weak_ptr

Nicht-besitzender Beobachter eines shared_ptr. Nützlich, um zirkuläre Referenzen aufzubrechen:

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // In shared_ptr umwandeln
    locked->attack();
}

Best Practices: Verwenden Sie standardmäßig unique_ptr für exklusiven Besitz. Verwenden Sie shared_ptr, wenn mehrere Objekte eine Ressource teilen müssen. Verwenden Sie weak_ptr, um zu beobachten, ohne die Lebensdauer zu verlängern. Bevorzugen Sie make_unique und make_shared gegenüber einem rohen new.

Probier es selbst

#include <iostream>
#include <memory>
#include <string>
#include "Document.h"

using namespace std;

int main() {
    string inputTitle;
    cin >> inputTitle;

    // TODO: Erstelle einen unique_ptr für ein Document mit inputTitle
    // unter Verwendung von std::make_unique

    // TODO: Gib "Unique owner: <title>" aus

    // TODO: Übertrage den Besitz auf einen anderen unique_ptr mittels std::move

    // TODO: Gib "Ownership transferred" aus

    // TODO: Erstelle einen shared_ptr für ein neues Document mit dem Titel "SharedDoc"
    // unter Verwendung von std::make_shared

    // TODO: Erstelle einen zweiten shared_ptr, der auf dasselbe Dokument zeigt

    // TODO: Gib "Shared owners: <count>" unter Verwendung von use_count() aus

    // TODO: Erstelle einen weak_ptr von einem der Shared Pointer

    // TODO: Verwende lock(), um über den weak_ptr auf das Dokument zuzugreifen
    // und gib "Weak access: <title>" aus

    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung