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