C++ 共享的ptr<;无效>;知道使用哪个析构函数吗?
我编写了以下代码来查看C++ 共享的ptr<;无效>;知道使用哪个析构函数吗?,c++,shared-ptr,void,C++,Shared Ptr,Void,我编写了以下代码来查看shared\u ptr是对shared\u ptr的最后一次引用并且自身被销毁时,它会如何运行 #include <iostream> #include <string> #include <memory> using namespace std; struct Thing{ ~Thing(){ cout<<"Destroyed\n"; } int data; }; int ma
shared\u ptr
是对shared\u ptr
的最后一次引用并且自身被销毁时,它会如何运行
#include <iostream>
#include <string>
#include <memory>
using namespace std;
struct Thing{
~Thing(){
cout<<"Destroyed\n";
}
int data;
};
int main(){
{
shared_ptr<void> voidPtr;
{
shared_ptr<Thing> thingPtr = make_shared<Thing>();
voidPtr = thingPtr;
}
cout<<"thingPtr is dead\n";
}
cout<<"voidPtr is dead\n";
return 0;
}
它的行为方式我喜欢,但这完全出乎意料,我想了解这里发生了什么。最初的共享指针不再存在,最后它只是一个
shared\u ptr
。因此,我希望这个共享指针的行为就像它持有一个void*
,并且不知道东西::~Thing()
,但它调用了它。这是故意的,对吗?void共享指针是如何实现这一点的?共享指针共同拥有的共享状态还包含一个deleter,一个类似函数的对象,它在托管对象的生命周期结束时被馈送给托管对象以释放它。我们甚至可以使用指定自己的删除程序。删除器的存储方式以及它所经历的任何类型擦除都是一个实现细节。但只要说共享状态包含一个函数就足够了,该函数确切地知道如何释放所拥有的资源
现在,当我们使用make_shared()
创建一个具体类型的对象,并且不提供删除程序时,共享状态被设置为保存一些默认的删除程序,这些删除程序可以释放对象。实现可以仅从模板参数生成一个。而且,由于其存储为共享状态的一部分,因此它不取决于任何共享状态所有权的shared\u指针的类型t
。它总是知道如何释放东西
因此,即使我们将voidPtr
作为唯一剩下的指针,删除器仍然保持不变,并且仍然知道如何释放对象。这就是当voidPtr
超出范围时它所做的。共享的ptr
只知道如何处理具有已知接口的管理对象。该管理对象提供两个引用计数(自身弱,受管对象强),以及包含删除器(只有在类型已知时才提供除调用之外的访问)和要删除的指针(私有)
shared\u ptr
指向的类型和对象与它使用的管理对象是完全不同的,尽管出于理智考虑,它不应该存在更长的寿命。我可以想象,shared\u ptr
的原始删除器在复制时会被保留。@πνταῥεῖ 显然,删除器从不存储在任何共享ptr实例中(无论是std::shared_ptr
还是任何具有共享功能的“拥有”智能ptr);它是动态分配的。
thingPtr is dead
Destroyed
voidPtr is dead