Sobes.tech
Middle

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

sobes.tech AI

Răspuns de la AI

std::unique_ptr — este un pointer inteligent care implementează proprietatea exclusivă asupra unui obiect alocat dinamic. Asigură gestionarea automată a memoriei: obiectul la care indică unique_ptr este șters automat la distrugerea unique_ptr.

Caracteristici cheie:

  • Proprietate exclusivă: În orice moment, doar un unique_ptr poate deține un anumit obiect.
  • Fără copiere: unique_ptr nu poate fi copiat. Acest lucru previne proprietatea multiplă asupra aceluiași obiect și problema "dublului ștergere".
  • Semantica de mutare: Proprietatea asupra obiectului poate fi transferată de la un unique_ptr la altul folosind semantica de mutare (std::move).
  • Deleter configurabil: Se poate furniza un deleter personalizat pentru gestionarea modurilor specifice de eliberare a resurselor.

Principiul de funcționare se bazează pe RAII (Resource Acquisition Is Initialization): resursa (memoria alocată dinamic) este achiziționată la crearea obiectului (unique_ptr) și eliberată la distrugere.

#include <memory> // Pentru unique_ptr
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass creat\n"; }
    ~MyClass() { std::cout << "MyClass distrus\n"; }
};

int main() {
    {   
        // Crearea unui unique_ptr care deține un obiect MyClass
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // În acest moment, ptr1 este proprietarul exclusiv al obiectului
        // auto ptr2 = ptr1; // Eroare de compilare: copiere interzisă

        // Transferul proprietății de la ptr1 la ptr2
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // După mutare, ptr1 nu mai deține obiectul (devine nullptr)
        if (!ptr1) {
            std::cout << "ptr1 nu deține obiect: " << (ptr1 ? "Da" : "Nu") << "\n";
        }

        // Domeniul de valabilitate pentru ptr2 se termină aici.
        // ptr2 este distrus, iar obiectul MyClass pe care îl deține este eliminat automat.
    } // Obiectul MyClass este distrus aici

    std::cout << "Sfârșitul main.\n";

    return 0;
}

Comparativ cu raw pointer:

Caracteristici raw pointer std::unique_ptr
Proprietate asupra resursei Nedefinit Excluziv
Ștergere automată Nu Da
Semantica de copiere Da Nu (doar mutare)
Riscul de scurgeri de memorie Ridicat Scăzut

În general, unique_ptr este metoda preferată pentru gestionarea memoriei dinamice în C++11 și versiunile ulterioare, atunci când este necesară o proprietate strictă și eliberare automată a resurselor.