19 c++ smart-pointers auto-ptr shared-ptr c++11
当尝试使用auto_ptr
带有forward-declaration声明的类型时,如下所示:
class A;
...
std::auto_ptr<A> a;
Run Code Online (Sandbox Code Playgroud)
A
没有调用析构函数(显然,因为auto_ptr
内部delete
的底层指针和不完整类型的析构函数不能被调用).
但是,相同的代码工作正常,并在使用时调用析构函数std::shared_ptr
而不是std::auto_ptr
.怎么解释?
Jam*_*lis 35
A shared_ptr
可以用不完整的类型声明,是的.在初始化或重置之前,不需要完成该类型.
初始化或重置a shared_ptr
以指向新对象时,它会创建一个"删除器",可用于销毁对象.例如,请考虑以下事项:
// somewhere where A is incomplete:
std::shared_ptr<class A> p;
// define A
class A { /* ... */ };
p.reset(new A());
Run Code Online (Sandbox Code Playgroud)
当你打电话时reset
,A
完成是因为你正在使用它创建一个实例new
.该reset
函数在内部创建并存储将用于销毁对象的删除器delete
.因为A
在这里完成,这delete
将是正确的事情.
通过这样做,声明时shared_ptr
不要求A
完整shared_ptr<A>
; 它只需要A
在shared_ptr
调用获取原始指针的构造函数或使用原始指针调用时完成reset
.
请注意,如果A
是不是当你这样做的这两件事一个完成的,shared_ptr
不会做正确的事,这种行为是未定义(这是在解释该文档boost::shared_ptr
,这可能是学习如何用最好的资源shared_ptr
正确,无论shared_ptr
你正在使用哪个版本(Boost,TR1,C++ 0x等)).
但是,只要您始终遵循最佳使用惯例 - shared_ptr
例如,如果您始终shared_ptr
使用指向调用的指针直接初始化和重置 - 您new
将不必担心违反此规则.
此功能不是免费的: shared_ptr
必须创建并存储指向删除器仿函数的指针; 通常这是通过将删除器存储为存储强弱引用计数的块的一部分,或者通过将指针作为指向删除器的块的一部分来存储(因为您可以提供自己的删除器).
auto_ptr
(unique_ptr
也是)被设计成没有任何开销:它上面的操作应该和使用哑指针一样有效.因此,auto_ptr
没有这个功能.