Ce code est-il correct?
auto v = make_unique<int>(12);
v.release(); // is this possible?
Est-ce équivalent à delete
d'un pointeur brut?
Non, le code provoque une fuite de mémoire. release
est utilisé pour libérer la propriété de l'objet géré sans le supprimer:
auto v = make_unique<int>(12); // manages the object
int * raw = v.release(); // pointer to no-longer-managed object
delete raw; // needs manual deletion
Ne le faites pas sauf si vous avez une bonne raison de jongler avec la mémoire brute sans filet de sécurité.
Pour supprimer l'objet, utilisez reset
.
auto v = make_unique<int>(12); // manages the object
v.reset(); // delete the object, leaving v empty
Ce code est-il correct?
Utilisez la fonction std::unique_ptr<>::reset()
pour supprimer le pointeur interne brut:
auto v = std::make_unique<int>(12);
v.reset(); // deletes the raw pointer
Une fois cette opération terminée, std::unique_ptr<>::get()
renverra nullptr
(sauf si vous avez fourni un paramètre non -nullptr
à std::unique_ptr<>::reset()
).
Ce code est-il correct?
Ce n'est pas et va fuir.
release()
laissez simplement le code appelant reprendre possession de la mémoire que le unique_ptr
a gardée jusqu'à ce qu'il soit appelé. Si vous n'affectez pas le pointeur renvoyé par release()
, vous aurez juste une fuite.
Une suppression explicite pour un unique_ptr
Serait reset()
. Mais rappelez-vous que unique_ptr
Sont là pour que vous n'ayez pas à gérer directement la mémoire qu'ils détiennent. Autrement dit, vous devez savoir qu'un unique_ptr
Supprimera en toute sécurité le pointeur brut sous-jacent une fois qu'il sera hors de portée.
Vous devriez donc avoir une très bonne raison d'effectuer la gestion manuelle de la mémoire sur un objet de gestion automatique de la mémoire.
release
perdra votre pointeur brut puisque vous ne l'attribuez à rien.
Il est destiné à être utilisé pour quelque chose comme
int* x = v.release();
Ce qui signifie que v
ne gère plus la durée de vie de ce pointeur, il délègue la propriété du pointeur brut à x
. Si vous ne faites que release
sans rien affecter, vous perdez le pointeur brut.
cela peut être un peu délicat pour des types arbitraires:
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * raw = v.release(); // pointer to no-longer-managed object
delete raw;
est presque correct.
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * ptr = v.release(); // pointer to no-longer-managed object
v.get_deleter() ( ptr );
celui-ci serait correct dans toutes les situations; il peut y avoir un deleter personnalisé défini sur le type Foo, mais utiliser le deleter renvoyé par l'objet unique_ptr convient à tous les cas.