常见类型
类型 | 出自 | 说明 |
---|---|---|
std::auto_ptr | C++0x | 强调auto(自动delete对象),copy时转移ownership(易误解),现已deprecated. |
std::shared_ptr | C++11 | 强调share(对象被多个owner共享),引用计数为0时delete对象. |
std::weak_ptr | C++11 | 强调weak(不改变引用计数),可解决循环引用问题,须lock得到std::shared_ptr后使用. |
std::unique_ptr | C++11 | 强调unique(只有一个owner),禁止copy,可以move,用于替代std::auto_ptr. |
boost::shared_ptr | boost | 类似std::shared_ptr, 强调share特性. |
boost::scoped_ptr | boost | 类似std::unique_ptr, 强调scope(超出作用域时delete对象),禁止copy,不能move. |
boost::weak_ptr | boost | 类似std::weak_ptr, 强调weak引用特性. |
android::sp | android | sp(strong pointer), 类似std::shared_ptr. |
android::wp | android | wp(weak pointer),类似std::weak_ptr,须promote成android::sp后使用. |
几点说明
1) 除上表列出的常见类型外,很多开源库(如Qt, Webkit, OpenCV等)都实现了满足自身需求的智能针指类型。
2)大多智能指针通过 “类 + 模板 + 引用计数” 来实现;通过重载操作符来模拟普通指针。
3)“weak”指针的引入主要是为了解决循环引用问题。
4)某些智能指针内部可能有多种引用计数。如android::sp的实现中有“weak”和“strong”两种引用计数。
5)考虑到多线程访问,智能指针引用计数的修改大多采用原子操作。
6)引用计数的变化规律:构造时加1,析构时减1,拷贝时一个加1,另一个减1。
7)引用计数本身需要存储,智能指针比普通指针多了引用计数的存储开销。
8)通常,引用计数所占的内存,在对象第1次被引用时分配,在对象析构(引用计数为0时,对象被delete)后释放。
9) 某些实现提供这样一个方法:分配内象内存和分配引用计数内存一步搞定。如std::make_shared。
10)善用智能指针可写出简单、安全、且不易出错的高质量代码。