La libreria standard C ++ 11 fornisce un'utilità per convertire da std::shared_ptr
a std::unique_ptr
o viceversa? Questa operazione è sicura?
shared_ptr
.
La libreria standard C ++ 11 fornisce un'utilità per convertire da std::shared_ptr
a std::unique_ptr
o viceversa? Questa operazione è sicura?
shared_ptr
.
Risposte:
std::unique_ptr
è il modo in C ++ 11 per esprimere la proprietà esclusiva, ma una delle sue caratteristiche più interessanti è che si converte facilmente ed efficacemente in un filestd::shared_ptr
.Questa è una parte fondamentale del motivo per cui
std::unique_ptr
è così adatto come tipo di ritorno di una funzione di fabbrica. Le funzioni di fabbrica non possono sapere se i chiamanti vorranno utilizzare la semantica della proprietà esclusiva per l'oggetto che restituiscono o se la proprietà condivisa (cioèstd::shared_ptr
) sarebbe più appropriata. Restituendo astd::unique_ptr
, le factory forniscono ai chiamanti il puntatore intelligente più efficiente, ma non impediscono ai chiamanti di sostituirlo con il suo fratello più flessibile.
std::shared_ptr
astd::unique_ptr
non è consentito. Una volta che hai trasformato la gestione della vita di una risorsa in unastd::shared_ptr
, non puoi cambiare idea. Anche se il conteggio dei riferimenti è uno, non puoi rivendicare la proprietà della risorsa per, ad esempio,std::unique_ptr
gestirla.Riferimento: Effective Modern C ++. 42 MODI SPECIFICI PER MIGLIORARE L'UTILIZZO DI C ++ 11 E C ++ 14. Scott Meyers.
In breve, puoi convertire facilmente ed efficientemente un std::unique_ptr
a in std::shared_ptr
ma non puoi convertirlo std::shared_ptr
in std::unique_ptr
.
Per esempio:
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
.
Dato unique_ptr u_ptr, crea shared_ptr s_ptr:
std::shared_ptr<whatever> s_ptr(u_ptr.release());
Andare dall'altra parte non è pratico.
std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
Deleter
all'interno diunique_ptr