mirror of
https://github.com/CnTransGroup/EffectiveModernCppChinese.git
synced 2025-01-26 11:50:46 +08:00
Update item19.md
Co-authored-by: Yang Yi <qingfeng.yy@alibaba-inc.com>
This commit is contained in:
parent
16bde493aa
commit
c614417bae
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user