Quote Originariamente inviata da ing82 Visualizza il messaggio
Ma quindi tendenzialmente, se ho dati membro di una classe dichiarati come puntatori, conviene definirli come smart pointer, così evito nel distruttore di dover richiamare il delete, corretto?
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.

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.
Con unique_ptr la faccenda è molto più semplice: non può essere copiato.
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;
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?
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.
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.