Sobes.tech
Middle

Cum funcționează shared_ptr în C++?

sobes.tech AI

Răspuns de la AI

shared_ptr — este un pointer inteligent care implementează semantica de proprietate a unei resurse partajate. Stochează un pointer către obiect și un pointer către blocul de control.

Blocul de control conține:

  • Contorul de referințe puternice (reference count).
  • Contorul de referințe slabe (weak count).
  • Functorul de ștergere personalizat (deleter), dacă este specificat.
  • Alocatorul personalizat, dacă este specificat.
  • Pointerul către obiectul stocat (același cu cel stocat în shared_ptr).

Principiul de funcționare:

  1. Crearea: La crearea primului shared_ptr care indică către un obiect, se creează blocul de control și se inițializează contorii de referințe: puternic — 1, slab — 0.
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Creează un obiect int și un bloc de control
    
  2. Copiere: La copierea unui shared_ptr, contorul de referințe puternice din blocul de control crește cu 1.
    std::shared_ptr<int> ptr2 = ptr1; // Crește contorul de referințe puternice
    
  3. Atribuire: La atribuirea unui shared_ptr, resursa veche este decrementată (contorul de referințe puternice scade), iar resursa nouă este incrementată (crește).
    std::shared_ptr<int> ptr3;
    ptr3 = ptr1; // Decrementă resursa veche a lui ptr3, Incrementază resursa lui ptr1
    
  4. Distrugere: La distrugerea unui shared_ptr (de exemplu, ieșirea din scope), contorul de referințe puternice scade.
    {
        std::shared_ptr<int> ptr4 = ptr1; // Crește contorul de referințe puternice
        // ptr4 iese din scope
    } // Scade contorul de referințe puternice
    
  5. Eliberarea resursei: Când contorul de referințe puternice ajunge la zero, resursa (obiectul indicat de shared_ptr) este eliminată folosind functorul de ștergere definit (sau delete implicit).
  6. Eliberarea blocului de control: Blocul de control este eliberat când ambele contoare (puternic și slab) ating zero.

Avantaje:

  • Gestionare automată a memoriei pentru resurse partajate.
  • Siguranță împotriva eliberărilor duble.
  • Suport pentru functori de ștergere personalizați.

Dezavantaje:

  • Referințele ciclice pot duce la scurgeri de memorie (weak_ptr rezolvă acest lucru).
  • Ușoară creștere a costurilor din cauza blocului de control și a operațiilor atomice asupra contoarelor.
  • Siguranță în operațiile cu propriu shared_ptr (copiere, atribuire, modificare pointer), dar nu și cu obiectul la care indică.