Sobes.tech
Middle

Come funziona unique_ptr in C++?

sobes.tech AI

Risposta dell'AI

std::unique_ptr — è un puntatore intelligente che implementa la proprietà esclusiva di un oggetto allocato dinamicamente. Garantisce la gestione automatica della memoria: l’oggetto a cui punta unique_ptr viene eliminato automaticamente alla distruzione di unique_ptr.

Caratteristiche principali:

  • Proprietà esclusiva: In ogni momento, solo un unique_ptr può possedere un determinato oggetto.
  • Assenza di copia: unique_ptr non può essere copiato. Questo previene la proprietà multipla dello stesso oggetto e il problema del "doppio eliminamento".
  • Semantica di movimento: La proprietà dell’oggetto può essere trasferita da un unique_ptr a un altro usando la semantica di movimento (std::move).
  • Deleter configurabile: È possibile fornire un deleter personalizzato per gestire modi specifici di liberare le risorse.

Il principio di funzionamento si basa su RAII (Resource Acquisition Is Initialization): la risorsa (memoria allocata dinamicamente) viene acquisita alla creazione dell’oggetto (unique_ptr) e liberata alla sua distruzione.

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

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

int main() {
    {   
        // Creazione di un unique_ptr che possiede un oggetto MyClass
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // In questo momento, ptr1 è il proprietario esclusivo dell’oggetto
        // auto ptr2 = ptr1; // Errore di compilazione: copia vietata

        // Trasferimento di proprietà da ptr1 a ptr2
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // Dopo il movimento, ptr1 non possiede più l’oggetto (diventa nullptr)
        if (!ptr1) {
            std::cout << "ptr1 non possiede oggetto: " << (ptr1 ? "Sì" : "No") << "\n";
        }

        // La durata di ptr2 termina qui.
        // ptr2 viene distrutto, e l’oggetto MyClass che possiede viene eliminato automaticamente.
    } // L’oggetto MyClass viene distrutto qui

    std::cout << "Fine main.\n";

    return 0;
}

Confronto con raw pointer:

Caratteristica raw pointer std::unique_ptr
Proprietà della risorsa Non definito Esclusiva
Eliminazione automatica No
Semantica di copia No (solo movimento)
Rischio di perdite di memoria Alto Basso

In generale, unique_ptr è il modo preferito per gestire la memoria dinamica in C++11 e versioni successive, quando si richiede proprietà rigorosa e rilascio automatico delle risorse.