A biblioteca padrão do C ++ 11 fornece algum utilitário para converter de a std::shared_ptr
para std::unique_ptr
ou vice-versa? Esta operação é segura?
shared_ptr
.
A biblioteca padrão do C ++ 11 fornece algum utilitário para converter de a std::shared_ptr
para std::unique_ptr
ou vice-versa? Esta operação é segura?
shared_ptr
.
Respostas:
std::unique_ptr
é a maneira do C ++ 11 de expressar propriedade exclusiva, mas um de seus recursos mais atraentes é que ele pode ser convertido de forma fácil e eficiente em umstd::shared_ptr
.Essa é uma parte importante do motivo
std::unique_ptr
pelo qual é tão adequado como um tipo de retorno de função de fábrica. As funções de fábrica não podem saber se os chamadores desejarão usar a semântica de propriedade exclusiva para o objeto que retornam ou se a propriedade compartilhada (ou seja,std::shared_ptr
) seria mais apropriada. Ao retornar umstd::unique_ptr
, as fábricas fornecem aos chamadores o ponteiro inteligente mais eficiente, mas não impedem que os chamadores o substituam por seu irmão mais flexível.
std::shared_ptr
parastd::unique_ptr
não é permitido. Depois de transformar o gerenciamento vitalício de um recurso em umstd::shared_ptr
, não há como mudar de ideia. Mesmo que a contagem de referência seja um, você não pode reivindicar a propriedade do recurso para, digamos,std::unique_ptr
gerenciá-lo.Referência: C ++ moderno eficaz. 42 MANEIRAS ESPECÍFICAS DE MELHORAR O USO DE C ++ 11 E C ++ 14. Scott Meyers.
Resumindo, você pode converter um std::unique_ptr
para de maneira fácil e eficiente, std::shared_ptr
mas não std::shared_ptr
para std::unique_ptr
.
Por exemplo:
std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);
ou:
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, crie shared_ptr s_ptr:
std::shared_ptr<whatever> s_ptr(u_ptr.release());
Seguir o outro caminho não é prático.
std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
Deleter
armazenado dentro dounique_ptr