TR1 引入了 shared_ptr、weak_ptr、scoped_ptr 和 unique_ptr 等。
我想知道这些类型之间的各种转换/类型提升规则。
例如,将 scoped_ptr 分配给 shared_ptr 时会发生什么?这种转换是否可能/有意义?这种转换有哪些用例?
(规范中有表格吗?)
TR1 引入了 shared_ptr、weak_ptr、scoped_ptr 和 unique_ptr 等。
我想知道这些类型之间的各种转换/类型提升规则。
例如,将 scoped_ptr 分配给 shared_ptr 时会发生什么?这种转换是否可能/有意义?这种转换有哪些用例?
(规范中有表格吗?)
首先,对您的问题进行一些更正:
scoped_ptr
是 Boost 的一部分,不包含在 C++ TR1 或 C++0x 中(预计在 C++0xunique_ptr
中可以在scoped_ptr
传统上使用的地方使用)。
unique_ptr
不是 C++ TR1 的一部分;它是 C++0x 的一部分(因为它依赖于右值引用和移动语义,这些仅在 C++0x 中可用)。
回答你的问题: 携手并进shared_ptr
。weak_ptr
a 拥有的对象shared_ptr
也可以被 a 引用weak_ptr
。它们是互补的。
Aunique_ptr
对其管理的对象拥有唯一所有权;没有其他人可以拥有该对象的所有权。这与 的所有权语义相反shared_ptr
:使用 a unique_ptr
,您拥有非共享的唯一所有权;与shared_ptr
您共享的非唯一所有权。
您可以shared_ptr
从 a 构造 a unique_ptr
; 当你这样做时,unique_ptr
失去对象的所有权。这是有效的,因为您始终知道给定unique_ptr
对象始终是对象的唯一所有者,因此它能够释放该所有权。
一旦对象由 a 拥有shared_ptr
,您就不能释放该对象的所有权,因为不能保证给定shared_ptr
的是该对象的唯一所有者。
给定两个类A
and B
(可能是智能指针类型),有四种主要方法可以将 type 的实例转换B
为 type A
:
(故意划线)。A
是一个可访问的基类对象B
(例如B
从 公开派生A
),并且转换可以切片或简单地调整引用或指针的类型。
A
有一个可访问的构造函数,采用B
.
B
有一个可访问的转换运算符产生一个A
.
存在一些接受 aB
并产生 a 的函数A
,而您正在调用该函数。
对于智能指针,继承不用于促进转换,因为继承允许不正确的转换;因此在上面删除。例如,如果SmartPtr<Derived>
从 公开继承SmartPtr<Base>
,则可以执行SmartPtr<Base>& spBase = spDerived;
,然后例如spBase = spOtherDerived
,这将是相当有问题的……在适当的高级抽象上,这与指针转换的问题基本相同const
;请参阅 FAQ 项目18.17 “为什么我在转换 Foo** → Foo const** 时出现错误?” .
因此,智能指针转换通常通过最后三个要点表示,即构造函数、转换运算符和命名转换函数。
本质上,C++0x 中有三个智能指针,忽略 deprecated auto_ptr
:
std::unique_ptr
对于单个对象。
std::unique_ptr
对于数组。
std::shared_ptr
对于单个对象。
unique_ptr
表示所有权转让,就像旧的auto_ptr
一样。但auto_ptr
不支持数组。unique_ptr
确实如此,这会影响可能的转换。
对于单个对象,unique_ptr
支持对应的原始指针通过构造函数进行的转换。它有一个unique_ptr
采用其他类型的模板化构造函数。参见例如 C++0x 草案 N3126 §20.9.10.2。
但是,对于与原始指针一样危险的数组!因此对于数组不unique_ptr
提供基本/派生转换。参见例如 C++0x 草案 N3126 §20.9.10.3。
由于在表示共享所有权unique_ptr
的同时表示所有权转移,因此无法从到进行安全的一般转换。但是,另外一种方式,Boost有一个构造函数 take ,而 C++0x保留了 this (也有它),自然而然地添加了一个构造函数taking 。参见 C++0x 草案 N3126 §20.9.11.2/1。shared_ptr
shared_ptr
unique_ptr
shared_ptr
auto_ptr
shared_ptr
unique_ptr
shared_ptr
通过构造函数和概念上实现“强制转换”的自由函数提供基本/派生转换。从本质上讲,这意味着shared_ptr
直接用于类类型对象的数组是非常危险的。为了那个用途,把它包起来。
如前所述,不支持将 from 转换shared_ptr
为一般操作。unique_ptr
因为共享所有权与所有权转移不直接兼容。但是,忽略并发症。线程安全,shared_ptr::unique
告诉您是否有一个所有者(即您的实例),然后,如果您对如何shared_ptr
构造初始值有必要的了解,则可以使用 free 函数get_deleter
获取指向删除器函数的指针,然后执行一些低级的恶作剧。如果你完全理解我在这里所说的,那么很好,很好。如果没有,那么我最好不要提供更多细节,因为这是一个非常非常特殊的情况,需要非常小心,并且您真的知道自己在做什么™。;-)
嗯,就是这样。我不是在讨论weak_ptr
,因为它只是shared_ptr
功能的一部分。但希望以上是您要问的。
scoped_ptr
AFAIK 不是 TR1 的一部分(如果我错了,请纠正我)。通常根本无法转让所有权boost
。scoped_ptr
一旦你给它分配了指针,你就不能释放它。unique_ptr
只能使用转让所有权std::move
,因此它也不会转让所有权。shared_ptr
无法释放所有权,因为其他指针可能与之共享。它可以转换为weak_ptr
. 如果您尝试转换它weak_ptr
并且对象被释放,它会抛出。weak_ptr
可以从 中创建,如果对象不再存在,则shared_ptr
转换为它可能会抛出。shared_ptr