EffectiveModernCppChinese/4.SmartPointers/item18.md
2019-07-01 09:25:42 +08:00

3.0 KiB
Raw Blame History

CHAPTER 4 Smart Pointers

诗人和歌曲作家喜欢爱。有时候喜欢计数。很少情况下两者兼有。受伊丽莎白·巴雷特·勃朗宁Elizabeth Barrett Browning对爱和数的不同看法的启发“我怎么爱你”让我数一数。”和保罗·西蒙Paul Simon“离开你的爱人必须有50种方法。”我们可以试着枚举一些为什么原始指针很难被爱的原因

  1. 它的声明不能指示所指到底是单个对象还是数组
  2. 它的声明没有告诉你用完后是否应该销毁它,即指针是否拥有所指之物
  3. 如果你决定你应该销毁对象所指没人告诉你该用delete还是其他析构机制比如将指针传给专门的销毁函数
  4. 如果你发现该用delete。 原因1说了不知道是delete单个对象还是delete数组。如果用错了结果是未定义的
  5. 假设你确定了指针所指,知道销毁机制,也很难确定你在所有执行路径上都执行了销毁操作(包括异常产生后的路径)。少一条路径就会产生资源泄漏,销毁多次还会导致未定义行为
  6. 一般来说没有办法告诉你指针是否变成了悬空指针dangling pointers即内存中不再存在指针所指之物。悬空指针会在对象销毁后仍然指向它们。

原始指针是强大的工具,当然,另一方面几十年的经验证明,只要注意力稍有疏忽,这个强大的工具就会攻击它的主人。

智能指针是解决这些问题的一种办法。智能指针包裹原始指针,它们的行为看起来像被包裹的原始指针,但避免了原始指针的很多陷阱。你应该更倾向于只能指针而不是原始指针。几乎原始指针能做的所有事情智能指针都能做,而且出错的机会更少。

std::auto_ptr是C++98的遗留物它是一次标准化的尝试后来变成了C++11的std::unique_ptr。要正确的模拟原生制作需要移动语义但是C++98没有这个东西。取而代之std::auto_ptr拉拢拷贝操作来达到自己的移动意图。这导致了令人奇怪的代码(拷贝一个std::auto_ptr会将它本身设置为null和令人沮丧的使用限制比如不能将std::auto_ptr放入容器)。

std::unique_ptr能做std::auto_ptr可以做的所有事情以及更多。它能高效完成任务,而且不会扭曲拷贝语义。在所有方面它都比std::unique_ptr好。现在std::auto_ptr唯一合法的使用场景就是代码使用C++98编译器编译。除非你有上述限制否则你就该把std::auto_ptr替换为std::unique_ptr而且绝不回头。

各种智能指针的API有极大的不同。唯一功能性相似的可能就是默认构造函数。因为有很多关于这些API的详细手册所以我将只关注那些API概览没有提及的内容比如值得注意的使用场景运行时性能分析

Item 18:对于独占资源使用std::unique_ptr

条款十八:对于独占资源使用std::unique_ptr