0%

智能指针

shared_ptr<void> 神奇不?

Why is shared_ptr<void> legal, while unique_ptr<void> is ill-formed?

智能指针类型转换时,自定义删除器怎么处理的?释放时执行自定义的删除器!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <memory>
#include <iostream>

using namespace std;
class Test
{
public:
Test() { cout << "ctor" << endl; }
~Test() { cout << "dtor" << endl; }
};
int main()
{
// 不会执行析构
void * rptr = new Test();
// 能够正确执行析构,为什么
shared_ptr<void> ptr(new Test());
auto unknow = ptr.get(); // "unknow" is "void *"

ptr = shared_ptr<char>(new char[10], [](auto *p) {
delete[] p;
cout << "check" << endl;
});
// 执行自定义的删除器,Test 的析构是不执行的
auto tPtr = static_pointer_cast<Test>(ptr);
return 0;
}

执行结果

1
2
3
4
5
ctor
ctor
dtor
check
请按任意键继续. . .

因为一个智能指针的变量除了被管理对象的指针(可以通过 get() 获得原始指针),它也存储了删除器(通过自定义删除器的方式可以看出),这个变量做 类型转换 时,只是改变了底层指针的类型,其删除器并未做任何改动,直接拷贝的。

The pointer held by the shared_ptr directly is the one returned by get(), while the pointer/object held by the control block is the one that will be deleted when the number of shared owners reaches zero. These pointers are not necessarily equal. 引用来源

shared_ptr构造函数 以及 拷贝赋值运算符 的描述中,都未描述跨类型的情况。只在 类型转换操作符 中,有详细解释。

The destructor of shared_ptr decrements the number of shared owners of the control block. If that counter reaches zero, the control block calls the destructor of the managed object. The control block does not deallocate itself until the std::weak_ptr counter reaches zero as well.

实现细节

weak_ptrlock() 如何实现的?计数器和管理对象都是普通对象,并非线程安全的。只针对计数器数值的增减操作是原子的,关键方法 _Ref_count_base::_Incref_nz()

高效但不简单,五体投地。

管理对象的指针是交给计数器子类型来实际管理的。

理解不透 enable_shared_from_this 的 Notes

Constructing a std::shared_ptr for an object that is already managed by another std::shared_ptr will not consult [请教;商量] the internally stored weak reference and thus will lead to undefined behavior.

需要区分 shared_ptr::_Reset()shared_ptr::_Resetp()

奇异递归模板模式虚继承 结合的“不可派生的类”,理解不透。 final 关键字了解一下

C++ 惯用法 CRTP 简介