¿La biblioteca estándar de C ++ 11 proporciona alguna utilidad para convertir de a std::shared_ptr
a std::unique_ptr
, o viceversa? ¿Es esta operación segura?
shared_ptr
.
¿La biblioteca estándar de C ++ 11 proporciona alguna utilidad para convertir de a std::shared_ptr
a std::unique_ptr
, o viceversa? ¿Es esta operación segura?
shared_ptr
.
Respuestas:
std::unique_ptr
es la forma en que C ++ 11 expresa la propiedad exclusiva, pero una de sus características más atractivas es que se convierte fácil y eficientemente astd::shared_ptr
.Esta es una parte clave de por qué
std::unique_ptr
es tan adecuado como tipo de retorno de función de fábrica. Las funciones de fábrica no pueden saber si las personas que llaman querrán utilizar la semántica de propiedad exclusiva para el objeto que devuelven o si la propiedad compartida (es decir,std::shared_ptr
) sería más apropiada. Al devolver unstd::unique_ptr
, las fábricas proporcionan a las personas que llaman el puntero inteligente más eficiente, pero no impiden que las personas que llaman lo reemplacen con su hermano más flexible.
std::shared_ptr
questd::unique_ptr
no está permitido. Una vez que haya entregado la gestión de por vida de un recurso a unstd::shared_ptr
, no hay forma de cambiar de opinión. Incluso si el recuento de referencias es uno, no puede reclamar la propiedad del recurso para, por ejemplo,std::unique_ptr
administrarlo.Referencia: C ++ moderno efectivo. 42 FORMAS ESPECÍFICAS DE MEJORAR EL USO DE C ++ 11 Y C ++ 14. Scott Meyers.
En resumen, puede convertir un std::unique_ptr
a de manera fácil y eficiente, std::shared_ptr
pero no puede convertir std::shared_ptr
a std::unique_ptr
.
Por ejemplo:
std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);
o:
std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");
std::unique_ptr
a a std::shared_ptr
.
Dado unique_ptr u_ptr, cree shared_ptr s_ptr:
std::shared_ptr<whatever> s_ptr(u_ptr.release());
Ir por el otro lado no es práctico.
std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
Deleter
almacenado dentro delunique_ptr