Czy biblioteka standardowa C ++ 11 zapewnia narzędzie do konwersji z formatu a std::shared_ptr
na std::unique_ptr
lub odwrotnie? Czy to bezpieczna operacja?
shared_ptr
.
Czy biblioteka standardowa C ++ 11 zapewnia narzędzie do konwersji z formatu a std::shared_ptr
na std::unique_ptr
lub odwrotnie? Czy to bezpieczna operacja?
shared_ptr
.
Odpowiedzi:
std::unique_ptr
jest sposobem C ++ 11 na wyrażenie wyłącznej własności, ale jedną z jego najbardziej atrakcyjnych cech jest to, że łatwo i wydajnie konwertuje się nastd::shared_ptr
.Jest to kluczowa część tego, dlaczego
std::unique_ptr
jest tak dobrze dopasowana jako typ zwracanej funkcji fabrycznej. Funkcje fabryczne nie mogą wiedzieć, czy wywołujący będą chcieli użyć semantyki wyłącznej własności dla obiektu, który zwracają, czy też współdzielona własność (tj.std::shared_ptr
) Byłaby bardziej odpowiednia. Zwracając astd::unique_ptr
, fabryki zapewniają dzwoniącym najbardziej wydajny inteligentny wskaźnik, ale nie utrudniają dzwoniącym zastąpienia go bardziej elastycznym rodzeństwem.
std::shared_ptr
abystd::unique_ptr
nie jest dozwolone. Gdy zmienisz zarządzanie zasobami przez całe życie na astd::shared_ptr
, nie możesz zmienić zdania. Nawet jeśli liczba odwołań wynosi jeden, nie możesz odzyskać prawa własności do zasobu, aby, powiedzmy, mieć plikstd::unique_ptr
Zarządzać nim.Odniesienie: Efektywne nowoczesne C ++. 42 SZCZEGÓLNE SPOSOBY POPRAWY KORZYSTANIA Z C ++ 11 I C ++ 14. Scott Meyers.
Krótko mówiąc, możesz łatwo i efektywnie przekonwertować std::unique_ptr
na, std::shared_ptr
ale nie możesz przekonwertować std::shared_ptr
na 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);
lub:
std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");
std::unique_ptr
do a std::shared_ptr
.
std::unique_ptr
do a std::shared_ptr
? Biblioteka standardowa definiuje operator przypisania przenoszenia template<class Y, class Deleter> shared_ptr& operator=(std::unique_ptr<Y, Deleter>&& r);
dla std::shared_ptr<T>
.
Biorąc pod uwagę unique_ptr u_ptr, utwórz shared_ptr s_ptr:
std::shared_ptr<whatever> s_ptr(u_ptr.release());
Odwrotna droga jest niepraktyczna.
std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
Deleter
przechowywane wunique_ptr