CPlusPlus智能指针简介

当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。

智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。

auto_ptr

auto_ptr的实现原理其实是在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针。

smart_ptr

智能指针(smart_ptr)是Boost各组件中,应用最为广泛的一个。

Boost从很早就提供了如下的智能指针,并且功能一直保持稳定:

  • scoped_ptr:不可拷贝与赋值,承载new,只能在 scoped_ptr 声明的作用域内使用。
  • scoped_array:不可拷贝与赋值,承载new []。
  • shared_ptr:可拷贝,承载new。boost 库中重要组成,重点学习。
  • shared_array:可拷贝,承载new []。
  • weak_ptr:弱引用。
  • intrusive_ptr:需要自实现计数功能的,引用计数智能指针。

smart_ptr的一种实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
template <typename T>  
class smart_ptr
{
public:
smart_ptr(T *p = 0): pointee(p), count(new size_t(1)) { } //初始的计数值为1
smart_ptr(const smart_ptr &rhs): pointee(rhs.pointee), count(rhs.count) { ++*count; } //拷贝构造函数,计数加1
~smart_ptr() { decr_count(); } //析构,计数减1,减到0时进行垃圾回收,即释放空间
smart_ptr& operator= (const smart_ptr& rhs) //重载赋值操作符
{
//给自身赋值也对,因为如果自身赋值,计数器先减1,再加1,并未发生改变
++*count;
decr_count();
pointee = rhs.pointee;
count = rhs.count;
return *this;
}
//重载箭头操作符和解引用操作符,未提供指针的检查
T *operator->() { return pointee; }
const T *operator->() const { return pointee; }
T &operator*() { return *pointee; }
const T &operator*() const { return *pointee; }
size_t get_refcount() { return *count; } //获得引用计数器值
private:
T *pointee; //实际指针,被代理
size_t *count; //引用计数器
void decr_count() //计数器减1
{
if(--*count == 0)
{
delete pointee;
delete count;
}
}
};

c++ 11智能指针

c++ 11 提供了3种智能指针:std::shared_ptr、std::unique_ptr、std::weak_ptr,使用时引用头文件

  • shared_ptr允许多个指针指向同一个对象
  • unique_ptr则“独占”所指向的对象
  • weak_ptr,它是一种弱引用,指向shared_ptr所管理的对象

参考链接

  1. 智能指针,by 百度百科。
  2. C++各类设计模式及实现详解,by linux.
  3. C++智能指针auto_ptr详解,by CHENG Jian.
  4. boost 学习笔记 4:智能指针 smart_ptr,by einverne.
  5. 研究C++类的成员变量构造析构顺序,by paokuflying.
  6. C++智能指针作为成员变量,by caesar1228.
  7. 为什么建议你用nullptr而不是NULL,by 守望.
  8. C++11动态内存与智能指针,by herryone123.