智能指针概述

一般来说,原始指针有以下缺点:

  1. 不能从声明中推断出它到底是指向单一对象还是数组。
  2. 不能从声明中推断出当你使用完毕后是否应当销毁其指向对象(即不能确定是否只有该指针指向那份资源)。
  3. 如果你确定应当销毁指针所指物,你无法明确当以何种方式完成销毁(使用delete还是存在专有销毁函数)。
  4. 如果你明确应当使用delete完成销毁,你也无法确定应当使用delete还是delete[]。
  5. 就算你解决了上述问题,你也无法保证销毁程序能够正确执行,可能它会被执行多次,也可能一次都不会执行。前者会导致未定义行为,后者则将导致资源泄漏。
  6. 无法判断当前指针是否空悬。

无疑,原始指针是相当强大的工具,但多年经验表明,好用者实繁,善用者盖寡,为了解决上述问题,C++引入了智能指针。智能指针是原始指针的外覆器,它们的行为与原始指针非常相似,但可以避开许多陷阱。

C++11有四个智能指针:std::auto_ptr,std::unique_ptr,std::shared_ptr与std :: weak_ptr。这些智能指针均旨在帮助管理动态分配对象的生命周期,即通过保证在适当的时间(包括异常情况下)以适当的方式销毁这些对象来避免资源泄漏。

std::auto_ptr是C++98设计下的失败品,C++11中的std::unique_ptr才是它的完全形态。理论来说,auto_ptr需要使用移动语义,但遗憾的是C++98中移动语义并不存在,因此 std::auto_ptr不得不使用copy来模拟move。这一特性直接导致auto_ptr存在一些奇怪的行为,例如auto_ptr拷贝会将其置为null,因此也无法将auto_ptr置于容器之中。std::unique_ptr能做所有auto_ptr能做的事,而且不存在那些约束,除非你是在C++98编译环境下,否则绝无使用auto_ptr的必要。

不同的智能指针API各不相同,可能唯一的共同点仅在于他们均存在默认构造函数。由于这些API的综合参考资料俯拾皆是,因此本章将重点讨论API概述并不关注之处,例如值得注意的用例,运行成本分析等等。通过掌握此类信息,开发者可以更加了解智能指针之间的区别以及如何高效地使用它们。