Tendenzialmente si, ma non c'è una regola fissa: occorre valutare quello che si vuole fare.
Lo shared_ptr mantiene un contatore interno di quante volte è stato copiato e l'ultimo a uscire cancella il puntatore, MA la memoria condivisa è la stessa. Se devi fare una deep copy dell'oggetto puntato lo devi fare esplicitamente.
Con unique_ptr la faccenda è molto più semplice: non può essere copiato.codice:shared_ptr<int> p = new int(10); // contatore = 1 shared_ptr<int> q = p; // contatore = 2 *q = 20; cout << *p << endl; // 20 perché il puntatore interno è condiviso tra p e q. shared_ptr<int> z = new int; *z = *q; *q = 30; cout << *z << endl; // 20 perché il puntatore interno di z non è condiviso con p e q. cout << *p << endl; // 30 perché il puntatore interno è condiviso tra p e q.
codice:unique_ptr<int> p(new int(10)) unique_ptr<int> q = p; // errore: unique_ptr non può essere copiato unique_ptr<int> q = std:move(p); // ma può essere spostato. // cout << *p << endl; crash: il puntatore interno di p ora è nullptr cout << *q << endl; // vale 10. unique_ptr<int> z (new int); *z = *q;Non proprio: userari shared_ptr se la tua classe dev'essere copiabile, quindi condividere il dato interno con copie di classe uguale; userai unique_ptr se non vuoi che la tua classe sia copiabile e quindi non condividere il dato interno con copie di classe uguale.Ne approfitto per una ulteriore domanda: se il dato membro di tipo puntatore sarà usato solo "interno" alla classe, uso unique_ptr, se invece sarà impiegato anche da qualche altro oggetto, uso shared_ptr, corretto?
Ambedue i puntatori possono essere restituiti da funzioni, ma se restituisci uno shared_ptr avrai il dato interno esistente, se usi uno unique_ptr stai dicendo: "classe X non devi più occuparti della gestione di unique_ptr<dato> perché ci pensa qualcun altro.
Spero di essermi spiegato.