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<<"Destroyedn";
}
int data;
};
int main(){
{
shared_ptr<void> voidPtr;
{
shared_ptr<Thing> thingPtr = make_shared<Thing>();
voidPtr = thingPtr;
}
cout<<"thingPtr is deadn";
}
cout<<"voidPtr is deadn";
return 0;
}
哪些输出:
thingPtr is dead
Destroyed
voidPtr is dead
它的行为方式是我喜欢的,但它完全出乎意料,我想了解这里发生了什么。 最初的共享指针不再存在,它最终只是一个shared_ptr<void>
。 所以我希望这个共享指针的行为就像它拿着一个void*
并且不知道Thing::~Thing()
,但它调用它。 这是设计使然,对吧? 空共享指针是如何实现这一点的?
共享指针共同拥有的共享状态还包含一个删除器,这是一个类似于对象的函数,在其生存期结束时馈送托管对象以释放它。我们甚至可以使用适当的构造函数指定我们自己的删除器。删除程序的存储方式以及它所经历的任何类型的擦除都是实现细节。但只要说共享状态包含一个函数就足够了,该函数确切地知道如何释放拥有的资源。
现在,当我们使用make_shared<Thing>()
创建具体类型的对象并且不提供删除器时,共享状态设置为保存一些可以释放Thing
的默认删除器。该实现可以仅从模板参数生成一个。由于它存储为共享状态的一部分,因此它不依赖于可能共享状态所有权的任何shared_pointer<T>
的类型T
。它将永远知道如何释放Thing
。
因此,即使我们将voidPtr
作为唯一剩下的指针,删除器也保持不变,并且仍然知道如何释放Thing
。当voidPtr
超出范围时,这就是它的作用。
shared_ptr
只知道如何处理具有已知接口的管理对象。该管理对象提供两个引用计数(自身较弱,托管对象为强),并包含删除器(仅在类型已知时提供调用之外的访问权限)和要删除的指针(私有)。
shared_ptr
指向什么类型和对象与它使用的管理对象完全分开,尽管为了理智起见,它不应该更长。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误