Le constructeur de unique_ptr<T>
accepte un pointeur brut vers un objet de type T
(donc, il accepte a T*
).
Dans le premier exemple:
unique_ptr<int> uptr (new int(3));
Le pointeur est le résultat d'une new
expression, tandis que dans le deuxième exemple:
unique_ptr<double> uptr2 (pd);
Le pointeur est stocké dans la pd
variable.
Conceptuellement, rien ne change (vous construisez un à unique_ptr
partir d'un pointeur brut), mais la deuxième approche est potentiellement plus dangereuse, car elle vous permettrait, par exemple, de faire:
unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);
Ainsi avoir deux pointeurs uniques qui encapsulent efficacement le même objet (violant ainsi la sémantique d'un pointeur unique ).
C'est pourquoi le premier formulaire de création d'un pointeur unique est préférable, lorsque cela est possible. Remarquez 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 ce doute qui est le vôtre:
Ce qui n'est pas non plus clair pour moi, c'est en quoi les pointeurs, déclarés de cette manière, seront différents des pointeurs déclarés de manière "normale".
Les pointeurs intelligents sont censés modéliser la propriété de l'objet et se charger automatiquement de détruire l'objet pointé lorsque le dernier pointeur (intelligent, propriétaire) vers cet objet tombe hors de portée.
De cette façon , vous n'avez pas à vous rappeler de faire delete
sur les objets attribués dynamiquement - le destructor du pointeur intelligent fera pour vous - ni à se soucier de savoir si vous ne serez pas déréférencer un (ballants) pointeur vers un objet qui a été détruit déjà:
{
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
Il unique_ptr
s'agit maintenant d' un pointeur intelligent qui modélise la propriété unique, ce qui signifie qu'à tout moment dans votre programme, il ne doit y avoir qu'un seul pointeur (propriétaire) vers l'objet pointé - c'est pourquoi il unique_ptr
n'est pas copiable.
Tant que vous utilisez des 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 divulguée et que la politique de propriété appropriée pour votre objet sera appliquée. Les pointeurs bruts ne vous donnent pas cette garantie.
new int(3)
renvoie un pointeur vers le nouveauint
, tout comme l'pd
était un pointeur vers le nouveaudouble
.