Update item19.md

Co-authored-by: Yang Yi <qingfeng.yy@alibaba-inc.com>
This commit is contained in:
猫耳堀川雷鼓 2021-02-20 21:02:41 +08:00 committed by GitHub
parent 16bde493aa
commit c614417bae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -46,7 +46,7 @@ std::vector<std::shared_ptr<Widget>> vpw{ pw1, pw2 };
另一个不同于`std::unique_ptr`的地方是,指定自定义删除器不会改变`std::shared_ptr`对象的大小。不管删除器是什么,一个`std::shared_ptr`对象都是两个指针大小。这是个好消息,但是它应该让你隐隐约约不安。自定义删除器可以是函数对象,函数对象可以包含任意多的数据。它意味着函数对象是任意大的。`std::shared_ptr`怎么能引用一个任意大的删除器而不使用更多的内存?
它不能。它必须使用更多的内存。然而,那部分内存不是`std::shared_ptr`对象的一部分。那部分在堆上面,或者`std::shared_ptr`创建者利用`std::shared_ptr`对自定义分配器的支持能力,那部分内存随便在哪都行。我前面提到了`std::shared_ptr`对象包含了所指对象的引用计数的指针。没错,但是有点误导人。因为引用计数是另一个更大的数据结构的一部分,那个数据结构通常叫做**控制块***control block*)。每个`std::shared_ptr`管理的对象都有个相应的控制块。控制块包含除了引用计数值外还有一个自定义删除器的拷贝,当然前提是存在自定义删除器。如果用户还指定了自定义分配器,控制块也会包含一个分配器的拷贝。控制块可能还包含一些额外的数据,正如[Item21](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/4.SmartPointers/item21.md)提到的,一个次级引用计数*weak count*,但是目前我们先忽略它。我们可以想象`std::shared_ptr`对象在内存中是这样:
它不能。它必须使用更多的内存。然而,那部分内存不是`std::shared_ptr`对象的一部分。那部分在堆上面,或者`std::shared_ptr`创建者利用`std::shared_ptr`对自定义分配器的支持能力,那部分内存随便在哪都行。我前面提到了`std::shared_ptr`对象包含了所指对象的引用计数的指针。没错,但是有点误导人。因为引用计数是另一个更大的数据结构的一部分,那个数据结构通常叫做**控制块***control block*)。每个`std::shared_ptr`管理的对象都有个相应的控制块。控制块除了包含引用计数值外还有一个自定义删除器的拷贝,当然前提是存在自定义删除器。如果用户还指定了自定义分配器,控制块也会包含一个分配器的拷贝。控制块可能还包含一些额外的数据,正如[Item21](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/4.SmartPointers/item21.md)提到的,一个次级引用计数*weak count*,但是目前我们先忽略它。我们可以想象`std::shared_ptr`对象在内存中是这样:
![item19_fig1](media/item19_fig1.png)