Il costruttore di unique_ptr<T>
accetta un puntatore grezzo a un oggetto di tipo T
(quindi accetta a T*
).
Nel primo esempio:
unique_ptr<int> uptr (new int(3));
Il puntatore è il risultato di new
un'espressione, mentre nel secondo esempio:
unique_ptr<double> uptr2 (pd);
Il puntatore è memorizzato nella pd
variabile.
Concettualmente, non cambia nulla (stai costruendo un unique_ptr
da un puntatore grezzo), ma il secondo approccio è potenzialmente più pericoloso, poiché ti consentirebbe, ad esempio, di fare:
unique_ptr<double> uptr2 (pd);
unique_ptr<double> uptr3 (pd);
Avendo così due puntatori univoci che incapsulano efficacemente lo stesso oggetto (violando così la semantica di un puntatore univoco ).
Questo è il motivo per cui il primo modulo per creare un puntatore univoco è migliore, quando possibile. Notare che in C ++ 14 saremo in grado di fare:
unique_ptr<int> p = make_unique<int>(42);
Che è sia più chiaro che più sicuro. Ora riguardo a questo tuo dubbio:
Ciò che inoltre non mi è chiaro, è come i puntatori, dichiarati in questo modo, saranno diversi dai puntatori dichiarati in modo "normale".
I puntatori intelligenti dovrebbero modellare la proprietà dell'oggetto e si occupano automaticamente di distruggere l'oggetto appuntito quando l'ultimo puntatore (intelligente, proprietario) a quell'oggetto esce dal campo di applicazione.
In questo modo non devi ricordare di aver fatto delete
su oggetti allocati dinamicamente - il distruttore del puntatore intelligente lo farà per te - né preoccuparti se non dereferenzerai un puntatore (penzolante) a un oggetto che è già stato distrutto:
{
unique_ptr<int> p = make_unique<int>(42);
}
Ora unique_ptr
è un puntatore intelligente che modella la proprietà unica, il che significa che in qualsiasi momento nel tuo programma ci sarà solo un puntatore (proprietario) all'oggetto appuntito - ecco perché unique_ptr
non è copiabili.
Finché utilizzi i puntatori intelligenti in un modo che non infrange il contratto implicito che richiedono di rispettare, avrai la garanzia che non verrà persa alcuna memoria e verrà applicata la politica di proprietà appropriata per il tuo oggetto. I puntatori grezzi non ti danno questa garanzia.
new int(3)
restituisce un puntatore al nuovoint
, proprio come lopd
era un puntatore al nuovodouble
.