shared_ptr<void> 如何知道要使用哪个析构函数?
How does shared_ptr<void> know which destructor to use?
我写了下面的代码来查看当 shared_ptr<void>
最后一次引用 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;
}
输出:
thingPtr is dead
Destroyed
voidPtr is dead
它的行为方式我喜欢,但这完全出乎意料,我想了解这里发生了什么。最初的共享指针已经不存在了,最后只是一个shared_ptr<void>
。所以我希望这个共享指针的行为就像它持有 void*
并且不知道 Thing::~Thing()
,但它会调用它。这是设计使然,对吧? void 共享指针是如何做到这一点的?
共享指针共同拥有的共享状态还包含一个删除器,一个类似于对象的函数,在其生命周期结束时将其提供给托管对象以释放它。我们甚至可以使用 appropriate constructor 指定我们自己的删除器。删除器是如何存储的,以及它所经历的任何类型擦除都是一个实现细节。但足以说明共享状态包含一个函数,该函数确切地知道如何释放所拥有的资源。
现在,当我们使用 make_shared<Thing>()
创建一个具体类型的对象并且不提供删除器时,共享状态将设置为保存一些可以释放 Thing
的默认删除器。该实现可以单独从模板参数生成一个。由于它作为共享状态的一部分存储,因此它不依赖于可能共享状态所有权的任何 shared_pointer<T>
的类型 T
。它总是知道如何释放 Thing
.
所以即使我们让 voidPtr
成为唯一剩余的指针,删除器仍然保持不变,并且仍然知道如何释放 Thing
。当 voidPtr
超出范围时它会做什么。
shared_ptr
只知道如何处理具有已知接口的管理对象。该管理对象提供两个引用计数(自身弱,被管理对象强),以及包含删除器(除了调用它之外的访问仅在类型已知时提供)和要删除的指针(私有) .
shared_ptr
指向的类型和对象与它使用的管理对象完全不同,尽管出于理智考虑,它不应该存在更长时间。
我写了下面的代码来查看当 shared_ptr<void>
最后一次引用 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;
}
输出:
thingPtr is dead
Destroyed
voidPtr is dead
它的行为方式我喜欢,但这完全出乎意料,我想了解这里发生了什么。最初的共享指针已经不存在了,最后只是一个shared_ptr<void>
。所以我希望这个共享指针的行为就像它持有 void*
并且不知道 Thing::~Thing()
,但它会调用它。这是设计使然,对吧? void 共享指针是如何做到这一点的?
共享指针共同拥有的共享状态还包含一个删除器,一个类似于对象的函数,在其生命周期结束时将其提供给托管对象以释放它。我们甚至可以使用 appropriate constructor 指定我们自己的删除器。删除器是如何存储的,以及它所经历的任何类型擦除都是一个实现细节。但足以说明共享状态包含一个函数,该函数确切地知道如何释放所拥有的资源。
现在,当我们使用 make_shared<Thing>()
创建一个具体类型的对象并且不提供删除器时,共享状态将设置为保存一些可以释放 Thing
的默认删除器。该实现可以单独从模板参数生成一个。由于它作为共享状态的一部分存储,因此它不依赖于可能共享状态所有权的任何 shared_pointer<T>
的类型 T
。它总是知道如何释放 Thing
.
所以即使我们让 voidPtr
成为唯一剩余的指针,删除器仍然保持不变,并且仍然知道如何释放 Thing
。当 voidPtr
超出范围时它会做什么。
shared_ptr
只知道如何处理具有已知接口的管理对象。该管理对象提供两个引用计数(自身弱,被管理对象强),以及包含删除器(除了调用它之外的访问仅在类型已知时提供)和要删除的指针(私有) .
shared_ptr
指向的类型和对象与它使用的管理对象完全不同,尽管出于理智考虑,它不应该存在更长时间。