- 明确的内存所有权,以及延伸的资源所有权,是良好设计的关键属性。有了明确的所有权,资源就能确保在需要时,及时创建并可用,在使用期间得到维护,并在不再需要时释放或清理。
- 资源泄漏,包括内存泄漏;悬空句柄(如指向不存在资源的指针、引用或迭代器等资源句柄);多次尝试释放同一资源;多次尝试构造同一资源。
- 非所有权、独占所有权、共享所有权,以及不同所有权类型之间的转换和所有权转移。
- 对于非所有权的函数和类,如果相应的所有权是通过拥有型指针管理的,则应通过原始指针和引用指向对象。如果对象由富指针或容器拥有,则问题会变得更复杂。如果富指针中包含的附加数据不需要,或只是访问容器中的单个元素,使用原始指针和引用完全足够。否则,应使用相应的非拥有型引用对象,例如 std::string_view 或 范围 库中的某个视图。如果没有可用的视图,则可能需要通过引用传递拥有型对象本身。
- 独占内存所有权更容易理解,并且更容易跟踪程序的控制流,也更加高效。
- 最好通过在栈上分配对象,或作为拥有类的数据成员(包括容器类)来实现。如果需要引用语义或特定的移动语义,应使用 unique 指针。对于条件性构造的对象,std::optional 是一个极佳的解决方案。
- 共享所有权应通过共享指针表达,例如 std::shared_ptr。
- 大型系统中,共享所有权难以管理,可能导致资源的释放不必要地延迟。与独占所有权相比,还存在显著的性能开销。在线程安全的并发程序中,维护共享所有权需要非常谨慎的实现。
- 视图如 std::string_view、std::span 以及 std::ranges 中的视图,本质上是非拥有的富指针。字符串视图之于字符串,就如同原始指针之于 unique 指针:一种非拥有的对象,包含其其拥有对象的信息。