C++ 删除指向不完整类型和智能指针的指针

C++ 删除指向不完整类型和智能指针的指针,c++,c++11,shared-ptr,smart-pointers,auto-ptr,C++,C++11,Shared Ptr,Smart Pointers,Auto Ptr,尝试将自动\u ptr与使用前向声明声明的类型一起使用时,如下所示: class A; ... std::auto_ptr<A> a; A类; ... 标准::自动测试a; 未调用A的析构函数(显然,因为auto_ptr内部deletes无法调用底层指针和不完整类型的析构函数) 但是,使用std::shared_ptr而不是std::auto_ptr时,同样的代码工作正常,并且调用析构函数。 如何解释呢?Ashared\u ptr可以用不完整的类型声明,是的。在初始化或重置该类型

尝试将
自动\u ptr
与使用前向声明声明的类型一起使用时,如下所示:

class A;
...
std::auto_ptr<A> a;
A类;
...
标准::自动测试a;
未调用
A
的析构函数(显然,因为
auto_ptr
内部
delete
s无法调用底层指针和不完整类型的析构函数)

但是,使用
std::shared_ptr
而不是
std::auto_ptr
时,同样的代码工作正常,并且调用析构函数。
如何解释呢?

A
shared\u ptr
可以用不完整的类型声明,是的。在初始化或重置该类型之前,该类型不需要完整

当您初始化或重置一个
共享\u ptr
以指向一个新对象时,它会创建一个可用于销毁该对象的“删除器”。例如,考虑以下内容:

// somewhere where A is incomplete:
std::shared_ptr<class A> p;

// define A
class A { /* ... */ };

p.reset(new A());
//某个不完整的地方:
std::共享的ptr p;
//定义一个
A类{/*…*/};
p、 重置(新的A());
调用
reset
时,
A
已完成,因为您正在使用
new
创建它的实例。
reset
函数在内部创建并存储一个删除器,该删除器将用于使用
delete
销毁对象。因为
A
在这里已经完成,所以
delete
将做正确的事情

通过这样做,
shared_ptr
不需要在
shared_ptr时完成
A
,这可能是学习如何正确使用
shared_ptr
的最佳资源,无论您使用的是
shared_ptr
的哪个版本(Boost、TR1、C++0x等)

但是,只要您始终遵循
共享ptr
的最佳使用实践——特别是,如果您总是直接使用调用
新的
生成的指针初始化和重置
共享ptr
,您就不必担心违反此规则

此功能不是免费的:
shared_ptr
必须创建并存储指向deleter functor的指针;通常,这是通过将删除器存储为存储强引用计数和弱引用计数的块的一部分,或者通过将指针作为指向删除器的块的一部分来实现的(因为您可以提供自己的删除器)


auto_ptr
(还有
unique_ptr
)的设计没有任何开销:对它的操作应该与使用哑指针一样高效。因此,
auto\u ptr
不具备此功能。

这里总结了unique\u ptr和shared\u ptr的完整性要求:对于shared\u ptr上一小时的高度娱乐性材料,请查看。同样值得一提的是
std::make_shared
。谢谢!以下是一个更新的链接,用于总结独特和共享的完整性要求: