- 让我们列举一下为什么很难爱上一个裸指针(raw pointers):
- 其声明不能指示其指向的是一个单独对象还是数组。
- 其声明不能告诉你应否在使用完毕时销毁它,换言之你不知道它是不是(独占地)拥有着它指向的东西。
- 如果你决心销毁它,你没有办法知道如何做到——你是应该用
delete
,还是有一套其它的销毁机制(或许是调用一个专门的函数)? - 如果你确定
delete
是合适的方法,原因一告诉我们你无法确定应该用单个对象销毁的delete
形式,还是数组销毁的delete []
形式。如果用错了,结果就是 undefined behaviour。 - 假设你的确搞清了它指向什么并且知道如何销毁,你还是很难保证销毁行为会在代码中任何可能的执行路径(包括异常)中都被执行 恰好一次 。遗漏了某个路径会导致资源泄漏,销毁多于一次则又是 undefined bahaviour。
- 通常没有办法判断一个指针是否是 悬空(dangle) 的,即它指向的内存是否已经不再存储它指向的对象。当物体已被销毁而指针仍指向它们时就会导致这种情况。
- C++11的 智能指针(smart pointer) 可以解决这些问题。它们是裸指针的封装,行为尽可能与裸指针近似,但绕过了很多坑点。智能指针可以做裸指针能做的任何事情,并且犯错的几率远远小于它。因此你应该倾向于使用智能指针而非裸指针。
- C++11中有四种智能指针:
std::auto_ptr
,std::unique_ptr
,std::shared_ptr
和std::weak_ptr
。std::auto_ptr
是C++98的产物,现在已经被废弃(deprecated)。由于没有移动语义,其表现在一些方面很奇怪,使用上也有很多限制。std::unique_ptr
可以做前者的所有工作以及更多。除非只能用C++98编译器,任何时候都应该使用std::unique_ptr
。
以下为各条款(Item)链接:
Item 18: 使用 std::unique_ptr 管理独占性资源
Item 19: 使用 std::shared_ptr 管理共享性资源
Item 20: 使用 std::weak_ptr 管理可能悬空的类似 std::shared_ptr 的指针
Item 21: 倾向于使用 std::make_unique 和 std::make_shared 而非直接使用 new
Item 22: 使用 Pimpl 手法时,在实现文件中定义特殊成员函数