C ++ 11 unique_ptr和shared_ptr是否能够转换为彼此的类型?


99

C ++ 11标准库是否提供任何实用程序来将转换std::shared_ptrstd::unique_ptr,反之亦然?这样安全吗?


请定义“安全操作”。您在寻找什么样的安全性?终身管理安全吗?线程安全?
jaggedSpire

2
“ STL”并不意味着标准库。STL与无关shared_ptr
curiousguy

1
@jaggedSpire线程安全性可能意味着你必须在不同的线程使用的业主,即利用数不为1
curiousguy

@curiousguy我知道。我的观点是,OP的问题中对“安全性”的定义不明确,他需要澄清他所指的是哪种“安全性”,因为存在多种类型。
jaggedSpire

Answers:


161

std::unique_ptr是C ++ 11表示专有所有权的方法,但是其最吸引人的功能之一是可以轻松,高效地转换为std::shared_ptr

这是为什么std::unique_ptr非常适合作为工厂函数返回类型的关键部分。工厂函数无法知道调用者是否要对它们返回的对象使用排他性所有权语义,或者共享所有权(即std::shared_ptr)是否更合适。通过返回a std::unique_ptr,工厂为调用者提供了最有效的智能指针,但它们不会阻止调用者用其更灵活的同级替换它。

std::shared_ptrstd::unique_ptr不允许。一旦将资源的生命周期管理转移到std::shared_ptr,就不会改变主意。即使引用计数为1,也无法收回对资源的所有权以进行std::unique_ptr管理。

参考:有效的现代C ++。改善您对C ++ 11和C ++ 14的使用的42种特定方法。斯科特·迈耶斯(Scott Meyers)。

简而言之,您可以轻松高效地将转换为std::unique_ptrstd::shared_ptr但不能转换std::shared_ptrstd::unique_ptr

例如:

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

要么:

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

9
...你怎么做呢?
杰克

4
@Jake我添加了一个示例
chema989

要知道,尽管不允许编译器(至少不是GCC)实际上将不会阻止(甚至是警告),如果你不小心(例如,通过改变一个成员变量的指针类型)分配std::unique_ptrstd::shared_ptr
StefanQ

-8

给定unique_ptr u_ptr,创建shared_ptr s_ptr:

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

走另一条路是不切实际的。


29
这是“正确”的方法:std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
emlai

6
这是学究式的“正确”方法:std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
polyvertex

3
有什么不安全的呢?
nmr

7
@VioletGiraffe•我想polyvertex提倡使用新的初始化列表语法-避免习惯成语的窄化转换,并以统一的语法容纳成员初始化-这是一种良好的习惯。六个,另一个六个?
Eljay

8
@nmr这是不安全的,因为您可能会丢失Deleter存储在其中的内容unique_ptr
Zang MingJie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.