Sostieni AppuntiFacili con una piccola donazione su PayPal
Dona con PayPalI puntatori intelligenti (smart pointer) in C++ sono oggetti che gestiscono automaticamente la memoria, liberando le risorse quando non servono più.
A differenza dei puntatori classici (int* ptr), non è necessario chiamare manualmente delete, riducendo il rischio di memory leak.
In C++ moderno esistono tre tipi principali di puntatori intelligenti:
unique_ptr: possiede esclusivamente l’oggetto puntato;shared_ptr: permette di condividere la proprietà dell’oggetto tra più puntatori;weak_ptr: puntatore debole, non incrementa il conteggio di riferimenti di uno shared_ptr.Un unique_ptr può avere solo un proprietario alla volta. Non può essere copiato, ma può essere trasferito con std::move.
Esempio:
#include <iostream>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> ptr = make_unique<int>(42);
cout << "Valore: " << *ptr << endl;
// unique_ptr<int> ptr_copy = ptr; // ERRORE: non copiabile
unique_ptr<int> new_ptr = move(ptr); // trasferimento della proprietà
// cout << *ptr << endl; // ERRORE: ptr non possiede più l'oggetto
cout << "Valore trasferito: " << *new_ptr << endl;
return 0;
}
INFO
make_unique è il modo consigliato per creare un unique_ptr perché garantisce sicurezza e ottimizzazione della memoria.
Un shared_ptr permette a più puntatori di condividere lo stesso oggetto. La memoria viene liberata solo quando l’ultimo shared_ptr che punta all’oggetto viene distrutto.
Esempio:
#include <iostream>
#include <memory>
using namespace std;
int main() {
shared_ptr<int> ptr1 = make_shared<int>(10);
shared_ptr<int> ptr2 = ptr1; // condividono la proprietà
cout << "p1: " << *ptr1 << ", p2: " << *ptr2 << endl;
// Quando ptr1 o ptr2 escono dallo scope, l'oggetto viene eliminato automaticamente
return 0;
}
INFO
make_shared è consigliato rispetto a shared_ptr<int>(new int(10)) perché riduce il numero di allocazioni e migliora le performance.
Un weak_ptr non possiede l’oggetto ma può accedervi se esiste ancora uno shared_ptr:
#include <iostream>
#include <memory>
using namespace std;
int main() {
shared_ptr<int> sp = make_shared<int>(50);
weak_ptr<int> wp = sp; // puntatore debole
if (auto temp = wp.lock()) { // converte weak_ptr in shared_ptr temporaneo
cout << "Valore: " << *temp << endl;
}
sp.reset(); // elimina lo shared_ptr
if (wp.expired()) {
cout << "L'oggetto non esiste più!" << endl;
}
return 0;
}
weak_ptr è utile per evitare cicli di riferimento che impediscono la liberazione della memoria.
delete non necessario);unique_ptr<int> con valore 100;shared_ptr<int> con valore 200;shared_ptr che condivide la proprietà;shared_ptr<int> con valore 300;lock() per stampare il valore se l’oggetto esiste;weak_ptr segnala che l’oggetto non esiste più.1) Cosa distingue un unique_ptr da un puntatore classico?
2) Quale operazione è necessaria per trasferire un unique_ptr?
3) Quando viene liberata la memoria di uno shared_ptr?
4) A cosa serve un weak_ptr?
5) Quale funzione viene consigliata per creare uno smart pointer?