2016-06-17 62 views
23

Czy biblioteka standardowa C++ 11 udostępnia narzędzie do konwersji z std::shared_ptr na std::unique_ptr lub odwrotnie? Czy to bezpieczna operacja?Czy C++ 11 unique_ptr i shared_ptr są w stanie przekonwertować na swój typ?

+0

Zdefiniuj "bezpieczną operację". Jakiego bezpieczeństwa szukasz? bezpieczeństwo zarządzania na całe życie? Bezpieczeństwo wątków? – jaggedSpire

+0

"STL" nie oznacza biblioteki standardowej. STL nie ma nic wspólnego z 'shared_ptr'. – curiousguy

+0

@jaggedSpire Bezpieczeństwo wątków oznaczałoby, że masz właścicieli używanych w różnych wątkach, tzn. Liczba użytkowników nie jest 1. – curiousguy

Odpowiedz

36

std::unique_ptr jest C++ 11 sposób wyrazić wyłączną własność, ale jeden z jego najbardziej atrakcyjnych cech jest to, że łatwo i skutecznie konwertuje do std:: shared_ptr.

Jest to kluczowy element, dlaczego std::unique_ptr jest tak dobrze nadaje się jako typ powrotu funkcji fabrycznej. Funkcje fabryczne nie mogą wiedzieć, czy wywołujący będą chcieli użyć wyłącznej semantyki własności dla zwracanego obiektu lub czy współdzielona własność (tj. std::shared_ptr) byłaby bardziej odpowiednia. Zwracając std::unique_ptr, fabryki zapewniają dzwoniącym najskuteczniejszy inteligentny wskaźnik, ale nie przeszkadzają one osobom zastępującym w zastąpieniu go bardziej elastycznym rodzeństwem.

std::shared_ptr do std::unique_ptr jest niedozwolone. Po zmianie zarządzania zasobami na całe życie na std::shared_ptr, nie zmieniasz zdania. Nawet jeśli licznik odwołań wynosi jeden, nie można odzyskać własności zasobu, aby np. Zarządzać nim.

Odniesienie: Skuteczne nowoczesne C++. 42 SZCZEGÓLNE SPOSOBY DOSKONALENIA UŻYCIA C++ 11 I C++ 14. Scott Meyers.

W skrócie, można łatwo i skutecznie konwertować std::unique_ptr do std::shared_ptr ale nie można konwertować std::shared_ptr do std::unique_ptr.

Na przykład:

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test"); 
std::shared_ptr<std::string> shared = std::move(unique); 

czyli

std::shared_ptr<std::string> shared = std::make_unique<std::string>("test"); 
+5

... Jak to zrobić? – Jake

+1

@Jake Dodałem przykład – chema989

0

Biorąc unique_ptr u_ptr utwórz shared_ptr s_ptr:

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

Idąc w drugą stronę jest niepraktyczny.

+13

Oto "właściwy" sposób: 'std :: shared_ptr s_ptr (std :: move (u_ptr));' – emlai

+0

I tutaj jest pedantyczny "właściwy" sposób: 'std :: shared_ptr s_ptr {std :: move (u_ptr)}; ' – polyvertex