Vai al contenuto
eLearner.app
Modulo 7 · Lezione 2 di 216/18 nel corso~12 min
Lezioni del modulo (2/2)

std::weak_ptr

Sebbene std::shared_ptr sia estremamente utile, l'uso esclusivo di proprietà condivisa può portare ad un problema noto come riferimento ciclico (o cyclic dependency).

Se due o più oggetti contengono ciascuno uno shared_ptr che punta all'altro, si crea un ciclo chiuso. In questa situazione, il contatore dei riferimenti di nessuno dei due oggetti scenderà mai a zero, impedendo la deallocazione ed originando un memory leak.

Cos'è std::weak_ptr

Per rompere i cicli di proprietà, la libreria standard offre std::weak_ptr. Si tratta di un puntatore intelligente che osserva un oggetto gestito da uno shared_ptr, ma senza incrementare il reference count.

Non possiede direttamente la risorsa, quindi non impedisce la sua distruzione.

Code
#include <memory>

std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Non incrementa il contatore!

Verificare e Accedere alla Risorsa

Poiché un weak_ptr non possiede la risorsa, questa potrebbe essere deallocata in qualsiasi momento (quando tutti gli shared_ptr associati vanno fuori scope).

Per utilizzare la risorsa osservata, dobbiamo prima:

  1. Controllare se è ancora valida usando expired().
  2. Convertire temporaneamente il weak_ptr in uno shared_ptr tramite il metodo lock(). Se la risorsa è ancora attiva, lock() restituisce uno shared_ptr valido, altrimenti restituisce un puntatore nullo (nullptr).
Code
if (!weak.expired()) {
    // lock() crea uno shared_ptr temporaneo per garantire l'accesso sicuro
    if (std::shared_ptr<int> sharedAccess = weak.lock()) {
        std::cout << *sharedAccess << std::endl;
    }
} else {
    std::cout << "Risorsa deallocata!" << std::endl;
}

Prova tu

Esercizio#cpp.m7.l2.e1
Tentativi: 0Caricamento…

Dichiara un std::weak_ptr<int> chiamato wPtr inizializzato a partire da sPtr. Dopodiché stampa il risultato booleano restituito da wPtr.expired() usando std::cout.

Caricamento editor…
Mostra suggerimento

Dichiara il `weak_ptr` indicando lo stesso tipo generico `<int>` ed assegna direttamente `sPtr` ad esso.

Soluzione disponibile dopo 3 tentativi

Esercizio#cpp.m7.l2.e2
Tentativi: 0Caricamento…

Usa il metodo lock() su wPtr per ottenere uno shared_ptr temporaneo. Se l'operazione ha successo (il puntatore non è nullo), stampa a schermo il valore dereferenziato.

Caricamento editor…
Mostra suggerimento

Inizializza una variabile dentro un blocco `if` richiamando `wPtr.lock()`, poi stampa la risorsa dereferenziandola con l'asterisco `*`.

Soluzione disponibile dopo 3 tentativi