shared_ptr <void>如何知道要使用哪个析构函数?

Ann*_*inn 34 c++ void shared-ptr

我编写了以下代码,以查看a shared_ptr<void>作为最后引用a shared_ptr<Thing>并被销毁时的行为。

#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;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出:

thingPtr is dead
Destroyed
voidPtr is dead
Run Code Online (Sandbox Code Playgroud)

它以我喜欢的方式运行,但是这完全是出乎意料的,我想了解这里发生了什么。最初的共享指针不再存在,最后只是一个shared_ptr<void>。因此,我希望这个共享指针的行为就像它持有a void*并且不知道有关Thing::~Thing(),但是它称之为。这是设计使然吧?void共享指针如何做到这一点?

Sto*_*ica 32

由共享指针共同拥有的共享状态还包含一个删除程序,该函数类似于对象,在其生存期结束时会被馈送给托管对象以释放它。我们甚至可以通过使用适当的构造函数来指定自己的删除程序。删除程序的存储方式以及删除程序所经历的任何类型擦除都是实现细节。只需说共享状态包含一个确切知道如何释放所拥有资源的函数即可。

现在,当我们使用创建一个具体类型的对象make_shared<Thing>()并且不提供删除器时,共享状态被设置为保存一些默认的删除器,该默认删除器可以释放Thing。该实现可以仅从模板参数生成一个。而且由于其存储为共享状态的一部分,因此它不依赖于可能共享该状态所有权的T任何类型shared_pointer<T>。它总是知道如何释放Thing

因此,即使我们voidPtr仅剩下一个指针,删除器仍保持不变,并且仍然知道如何释放a ThingvoidPtr超出范围时该怎么办。