Différences entre std:: make unique et std:: unique ptr
Ne std::make_unique
ont tout les avantages d'efficacité comme std::makes_shared
?
comparé à la construction manuelle de std::unique_ptr
:
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
3 réponses
la motivation derrière make_unique
est principalement double:
-
make_unique
est sûr pour la création de temporaires1, alors qu'avec l'utilisation explicite denew
vous devez vous rappeler la règle de ne pas utiliser de temporaires1 sans nom.foo(make_unique<T>(), make_unique<U>()); // exception safe foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
-
L'ajout de
make_unique
enfin, nous pouvons dire aux gens de ne "jamais" utilisernew
plutôt que la règle précédente ""jamais" utilisernew
sauf quand vous faites ununique_ptr
".
il y a aussi une troisième raison:
-
make_unique
ne nécessite pas d'utilisation de type redondant.unique_ptr<T>(new T())
->make_unique<T>()
aucune des raisons n'est liée à l'amélioration de l'efficacité de fonctionnement comme le fait l'utilisation de make_shared
(en raison du fait d'éviter une deuxième allocation, au prix d'une utilisation de mémoire de pointe potentiellement plus élevée).
* on s'attend à ce que C++17 comprenne un changement de règle qui signifie que cela n'est plus dangereux. Voir documents du comité c++ P0400R0 et P0145R3 .
std::make_unique
et std::make_shared
sont là pour deux raisons:
- de sorte que vous n'ayez pas à énumérer explicitement les arguments de type de template.
- sécurité d'exception supplémentaire par rapport à l'utilisation des constructeurs
std::unique_ptr
oustd::shared_ptr
. (Voir les Notes section ici .)
ce n'est pas vraiment une question d'efficacité de fonctionnement. Il y a le morceau sur le bloc de contrôle et le T
être affecté tout d'un coup, mais je pense que c'est plus un bonus et moins une motivation pour ces fonctions d'exister.
une raison pour laquelle vous devez utiliser std::unique_ptr(new A())
ou std::shared_ptr(new A())
directement au lieu de std::make_*()
est d'être incapable d'accéder au constructeur de la classe A
en dehors du champ d'application actuel.