2016-06-17 43 views
23

La libreria standard C++ 11 fornisce qualsiasi utilità per convertire da std::shared_ptr a std::unique_ptr o viceversa? Questa operazione è sicura?C++ 11 unique_ptr e shared_ptr è in grado di convertire il tipo dell'altro?

+0

Definire "operazione sicura" per favore. Che tipo di sicurezza stai cercando? sicurezza di gestione a vita? Filo di sicurezza? – jaggedSpire

+0

"STL" non significa libreria standard. L'STL non ha nulla a che fare con 'shared_ptr'. – curiousguy

+0

@jaggedSpire La sicurezza del thread significherebbe che i proprietari sono utilizzati in thread diversi, ovvero il conteggio degli usi non è 1. – curiousguy

risposta

36

std::unique_ptr è il modo in C++ 11 per esprimere proprietà esclusiva, ma uno dei suoi caratteristiche più interessanti è che semplice ed efficiente converte in std:: shared_ptr.

Questa è una parte fondamentale del motivo per cui lo std::unique_ptr è particolarmente adatto come tipo di ritorno di una funzione di fabbrica. Le funzioni di fabbrica non possono sapere se i chiamanti desiderano utilizzare la semantica della proprietà esclusiva per l'oggetto restituito o se la proprietà condivisa (ad esempio, std::shared_ptr) sia più appropriata. Restituendo uno std::unique_ptr, le fabbriche forniscono ai chiamanti il ​​puntatore intelligente più efficiente, ma non impediscono ai chiamanti di sostituirlo con il fratello più flessibile.

std::shared_ptr a std::unique_ptr non è consentito. Una volta che hai trasformato la gestione a vita di una risorsa in un std::shared_ptr, non cambierai idea. Anche se il conteggio dei riferimenti è uno, non è possibile recuperare la proprietà della risorsa per, ad esempio, avere una std::unique_ptr gestirla.

Riferimento: Efficace C++ moderno. 42 MODI SPECIFICI PER MIGLIORARE L'USO DI C++ 11 E C++ 14. Scott Meyers.

In breve, è possibile convertire facilmente e in modo efficiente una std::unique_ptr per std::shared_ptr, ma non è possibile convertire std::shared_ptr a std::unique_ptr.

Ad 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"); 
+5

... Come si fa? – Jake

+1

@Jake Ho aggiunto un esempio – chema989

0

Dato u_ptr unique_ptr, creare shared_ptr s_ptr:

std::shared_ptr<whatever> s_ptr(u_ptr.release()); 

In senso contrario è impraticabile.

+13

Ecco il modo "giusto": 'std :: shared_ptr s_ptr (std :: move (u_ptr));' – emlai

+0

E qui c'è il pedante modo "giusto": 'std :: shared_ptr s_ptr {std :: move (u_ptr)}; ' – polyvertex