Sobes.tech
Middle

Hoe werkt shared_ptr in C++?

sobes.tech AI

Antwoord van AI

shared_ptr — het slimme pointer dat de eigendomsssemantiek van een gedeelde resource implementeert. Het slaat een pointer naar het object en een pointer naar het controleblok op.

Het controleblok bevat:

  • Teller voor sterke referenties (reference count).
  • Teller voor zwakke referenties (weak count).
  • Aangepaste deleter (verwijderder), indien ingesteld.
  • Aangepaste allocator, indien ingesteld.
  • Pointer naar het opgeslagen object (hetzelfde als in shared_ptr).

Werking:

  1. Aanmaak: Bij het aanmaken van de eerste shared_ptr die naar een object wijst, wordt het controleblok aangemaakt en worden de tellers geïnitialiseerd: sterk — 1, zwak — 0.
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Maakt een int-object en een controleblok
    
  2. Kopiëren: Bij het kopiëren van een shared_ptr wordt de teller voor sterke referenties in het controleblok verhoogd met 1.
    std::shared_ptr<int> ptr2 = ptr1; // Verhoogt de teller voor sterke referenties
    
  3. Toewijzing: Bij het toewijzen van een shared_ptr wordt de oude resource gedecrementeerd (sterke referentieteller verlaagt), en de nieuwe resource wordt geïncrementeerd (verhoogd).
    std::shared_ptr<int> ptr3;
    ptr3 = ptr1; // Decrementeert de oude resource van ptr3, Incrementeert de resource van ptr1
    
  4. Verwijdering: Bij het vernietigen van een shared_ptr (bijvoorbeeld, uit scope gaan), wordt de sterke referentieteller verminderd.
    {
        std::shared_ptr<int> ptr4 = ptr1; // Verhoogt de sterke referentieteller
        // ptr4 gaat uit scope
    } // Verlaagt de sterke referentieteller
    
  5. Vrijgave van resource: Wanneer de sterke referentieteller nul bereikt, wordt de resource (het object waar shared_ptr naar wijst) verwijderd met behulp van de gedefinieerde deleter (of standaard delete).
  6. Vrijgave van controleblok: Het controleblok wordt vrijgegeven wanneer beide tellers (sterk en zwak) nul bereiken.

Voordelen:

  • Automatisch geheugenbeheer voor gedeelde resources.
  • Veiligheid tegen dubbele vrijgave.
  • Ondersteuning voor aangepaste deleters.

Nadelen:

  • Cyclic references kunnen leiden tot geheugenlekken (weak_ptr wordt gebruikt om dit te voorkomen).
  • Kleine overhead door het controleblok en atomische operaties op de tellers.
  • Veiligheid bij operaties met de eigen shared_ptr (kopiëren, toewijzen, wijzigen van de opgeslagen pointer), maar niet met het object waarnaar het wijst.