Le constructeur de unique_ptr<T>
accepte un pointeur brut vers un objet de type T
(donc, il accepte un T*
).
Dans le premier exemple :
unique_ptr<int> uptr (new int(3));
Le pointeur est le résultat d'un new
alors que dans le second exemple :
unique_ptr<double> uptr2 (pd);
Le pointeur est stocké dans le pd
variable.
D'un point de vue conceptuel, rien ne change (vous construisez une unique_ptr
à partir d'un pointeur brut), mais la seconde approche est potentiellement plus dangereuse, car elle vous permettrait, par exemple, de faire :
unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);
Ayant ainsi deux des pointeurs uniques qui encapsulent effectivement le même objet (violant ainsi la sémantique d'un pointeur de type unique pointeur).
C'est pourquoi la première forme de création d'un pointeur unique est préférable, lorsque cela est possible. Notez qu'en C++14 nous pourrons faire :
unique_ptr<int> p = make_unique<int>(42);
Ce qui est à la fois plus clair et plus sûr. Maintenant, concernant votre doute :
Ce qui n'est pas clair non plus pour moi, c'est la façon dont les pointeurs, déclarés de cette façon, seront différents des pointeurs déclarés de façon "normale".
Les pointeurs intelligents sont censés modéliser la propriété de l'objet, et se chargent automatiquement de détruire l'objet pointé lorsque le dernier pointeur (intelligent, propriétaire) de cet objet sort de sa portée.
Ainsi, vous n'avez pas à vous souvenir de faire delete
sur les objets alloués dynamiquement - le destructeur du pointeur intelligent s'en chargera pour vous - ni de s'inquiéter de savoir si vous ne déréférencerez pas un pointeur (flottant) vers un objet qui a déjà été détruit :
{
unique_ptr<int> p = make_unique<int>(42);
// Going out of scope...
}
// I did not leak my integer here! The destructor of unique_ptr called delete
Maintenant unique_ptr
est un pointeur intelligent qui modélise la propriété unique, ce qui signifie qu'à tout moment dans votre programme il n'y aura que un (propriétaire) de l'objet pointé - c'est la raison pour laquelle unique_ptr
est non copiable.
Tant que vous utilisez les pointeurs intelligents d'une manière qui ne rompt pas le contrat implicite qu'ils vous demandent de respecter, vous aurez la garantie qu'aucune mémoire ne sera perdue et que la politique de propriété appropriée pour votre objet sera appliquée. Les pointeurs bruts ne vous donnent pas cette garantie.