本篇笔记包含 Term 18~22。

Term 18:使用 std::unique_ptr 管理具备专属所有权的资源

  1. std::unique_ptr 是只移类型的智能指针,对托管资源有专属所有权
  2. 默认采用 delete 析构资源,也可以使用自定义函数作为删除器(通常是 lambda 函数),使用带状态的 lambda 函数或者函数指针作为删除器会增加智能指针对象大小
  3. std::unique_ptr 容易转换为 std::shared_ptr

Term 19:使用 std::shared_ptr 管理具备共享所有权的资源

  1. std::shared_ptr 可复制可移动,计数管理
  2. std::shared_ptr 大小是裸指针的两倍,使用动态分配的控制块来管理,计数操作必须是原子性的
  3. 默认采用 delete 析构资源,也可以使用自定义函数作为删除器,删除器型别与 std::shared_ptr 型别无关
  4. 避免使用裸指针创建 std::shared_ptr,会创建多余的控制块,析构时出错

Term 20:对于类似 std::shared_ptr 但有可能空悬的指针使用 std::weak_ptr

  1. 使用 std::weak_ptr 代替可能空悬的 std::shared_ptrstd::weak_ptr::lock 返回一个 std::shared_ptr,若空悬其为空
  2. 可能会使用 std::weak_ptr 的场景:缓存,观察者列表,避免 std::shared_ptr 指针环路

Term 21:优先选用 std::make_unique 和 std::make_shared,而非直接使用 new

  1. 相比于直接使用 new,make 系列函数代码简短,且异常安全,并且 std::make_sharedstd::allocated_shared 生成的目标码更优
  2. 不适于使用 make 系列函数的场景包括需要定制删除器,以及期望直接传递大括号初始化物
  3. 对于 std::shared_ptr,不建议使用 make 系列函数的额外场景有:自定义内存管理的类;内存紧张的系统,非常大的对象,以及存在比 std::shared_ptr 生存期更久的 std::weak_ptr

Term 22:Pimpl 习惯用法时,将特殊成员函数的定义放到实现文件中

对于采用 std::unique_ptr 来实现的 pImpl 指针,需要在头文件中声明特种成员函数,但是在实现文件中实现他们(使用 =default 也可以)