Sobes.tech
Middle

Wie funktioniert shared_ptr in C++?

sobes.tech KI

Antwort von AI

shared_ptr — ist ein intelligenter Zeiger, der die Besitzsemantik einer geteilten Ressource implementiert. Er speichert einen Zeiger auf das Objekt und einen Zeiger auf den Steuerblock.

Der Steuerblock enthält:

  • Zähler für starke Referenzen (reference count).
  • Zähler für schwache Referenzen (weak count).
  • Benutzerdefinierter Löschfunktor (deleter), falls angegeben.
  • Benutzerdefinierter Allokator, falls angegeben.
  • Zeiger auf das gespeicherte Objekt (das gleiche wie im shared_ptr).

Funktionsweise:

  1. Erstellung: Beim Erstellen des ersten shared_ptr, der auf ein Objekt zeigt, wird der Steuerblock erstellt, und die Referenzzähler werden initialisiert: stark — 1, schwach — 0.
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Erstellt ein int-Objekt und einen Steuerblock
    
  2. Kopie: Beim Kopieren eines shared_ptr erhöht sich der Zähler für starke Referenzen im Steuerblock um 1.
    std::shared_ptr<int> ptr2 = ptr1; // Erhöht den Zähler für starke Referenzen
    
  3. Zuweisung: Beim Zuweisen eines shared_ptr wird die alte Ressource dekrementiert (starker Referenzzähler sinkt), und die neue Ressource wird inkrementiert (steigt).
    std::shared_ptr<int> ptr3;
    ptr3 = ptr1; // Dekrementiert die alte Ressource von ptr3, Inkrementiert die Ressource von ptr1
    
  4. Löschung: Beim Zerstören eines shared_ptr (z.B. Verlassen des Gültigkeitsbereichs) wird der Zähler für starke Referenzen dekrementiert.
    {
        std::shared_ptr<int> ptr4 = ptr1; // Erhöht den Zähler für starke Referenzen
        // ptr4 verlässt den Gültigkeitsbereich
    } // Dekrementiert den Zähler für starke Referenzen
    
  5. Freigabe der Ressource: Wenn der Zähler für starke Referenzen null erreicht, wird die Ressource (das Objekt, auf das shared_ptr zeigt) mit dem definierten Löschfunktor (oder delete standardmäßig) gelöscht.
  6. Freigabe des Steuerblocks: Der Steuerblock wird freigegeben, wenn beide Zähler (stark und schwach) null erreichen.

Vorteile:

  • Automatische Speicherverwaltung für geteilte Ressourcen.
  • Sicherheit vor doppeltem Freigeben.
  • Unterstützung benutzerdefinierter Löschfunktoren.

Nachteile:

  • Zyklische Referenzen können zu Speicherlecks führen (gelöst mit weak_ptr).
  • Geringfügiger Mehraufwand durch Steuerblock und atomare Operationen an den Zählern.
  • Sicherheit bei Operationen mit dem eigenen shared_ptr (Kopieren, Zuweisung, Änderung des gespeicherten Zeigers), aber nicht mit dem Objekt, auf das er zeigt.