diff --git a/4.SmartPointers/item19.html b/4.SmartPointers/item19.html index 1328ad8..81008a4 100644 --- a/4.SmartPointers/item19.html +++ b/4.SmartPointers/item19.html @@ -256,7 +256,7 @@ private:

了解了动态分配控制块,任意大小的删除器和分配器,虚函数机制,原子性的引用计数修改,你对于std::shared_ptr的热情可能有点消退。可以理解,对每个资源管理问题来说都没有最佳的解决方案。但就它提供的功能来说,std::shared_ptr的开销是非常合理的。在通常情况下,使用默认删除器和默认分配器,使用std::make_shared创建std::shared_ptr,产生的控制块只需三个word大小。它的分配基本上是无开销的。(开销被并入了指向的对象的分配成本里。细节参见Item21)。对std::shared_ptr解引用的开销不会比原始指针高。执行需要原子引用计数修改的操作需要承担一两个原子操作开销,这些操作通常都会一一映射到机器指令上,所以即使对比非原子指令来说,原子指令开销较大,但是它们仍然只是单个指令上的。对于每个被std::shared_ptr指向的对象来说,控制块中的虚函数机制产生的开销通常只需要承受一次,即对象销毁的时候。

作为这些轻微开销的交换,你得到了动态分配的资源的生命周期自动管理的好处。大多数时候,比起手动管理,使用std::shared_ptr管理共享性资源都是非常合适的。如果你还在犹豫是否能承受std::shared_ptr带来的开销,那就再想想你是否需要共享所有权。如果独占资源可行或者可能可行,用std::unique_ptr是一个更好的选择。它的性能表现更接近于原始指针,并且从std::unique_ptr升级到std::shared_ptr也很容易,因为std::shared_ptr可以从std::unique_ptr上创建。

反之不行。当你的资源由std::shared_ptr管理,现在又想修改资源生命周期管理方式是没有办法的。即使引用计数为一,你也不能重新修改资源所有权,改用std::unique_ptr管理它。资源和指向它的std::shared_ptr的签订的所有权协议是“除非死亡否则永不分开”。不能分离,不能废除,没有特许。

-

std::shared_ptr不能处理的另一个东西是数组。和std::unique_ptr不同的是,std::shared_ptr的API设计之初就是针对单个对象的,没有办法std::shared_ptr<T[]>。一次又一次,“聪明”的程序员踌躇于是否该使用std::shared_ptr<T>指向数组,然后传入自定义删除器来删除数组(即delete [])。这可以通过编译,但是是一个糟糕的主意。一方面,std::shared_ptr没有提供operator[],所以数组索引操作需要借助怪异的指针算术。另一方面,std::shared_ptr支持转换为指向基类的指针,这对于单个对象来说有效,但是当用于数组类型时相当于在类型系统上开洞。(出于这个原因,std::unique_ptr<T[]> API禁止这种转换。)更重要的是,C++11已经提供了很多内置数组的候选方案(比如std::arraystd::vectorstd::string)。声明一个指向傻瓜数组的智能指针(译注:也是”聪明的指针“之意)几乎总是表示着糟糕的设计。

+

std::shared_ptr不能处理的另一个东西是数组。和std::unique_ptr不同的是,std::shared_ptr的API设计之初就是针对单个对象的,没有办法std::shared_ptr<T[]>。(译者注: 自 C++17 起 std::shared_ptr 可以用于管理动态分配的数组,使用 std::shared_ptr<T[]>)一次又一次,“聪明”的程序员踌躇于是否该使用std::shared_ptr<T>指向数组,然后传入自定义删除器来删除数组(即delete [])。这可以通过编译,但是是一个糟糕的主意。一方面,std::shared_ptr没有提供operator[],所以数组索引操作需要借助怪异的指针算术。另一方面,std::shared_ptr支持转换为指向基类的指针,这对于单个对象来说有效,但是当用于数组类型时相当于在类型系统上开洞。(出于这个原因,std::unique_ptr<T[]> API禁止这种转换。)更重要的是,C++11已经提供了很多内置数组的候选方案(比如std::arraystd::vectorstd::string)。声明一个指向傻瓜数组的智能指针(译注:也是”聪明的指针“之意)几乎总是表示着糟糕的设计。

请记住: