理解shared_ptr<T>

1、shared_ptr<T>解决什么问题?

  auto_ptr有个局限,拥有权转移。这往往不符合我们的需求,有时候我们期望,多个资源管理对象可以共享一个资源,当引用计数为0的时候,执行delete。shared_ptr就是为了解决这个问题。

2、shared_ptr怎么解决这个问题?和auto_ptr类似,除此之外,还有几点需要注意:

3、增加一个字段为引用计数,当引用计数为0的时候,执行delete。引用计数字段不能放在资源管理类中,为什么?

  假设放到资源管理类中,每个资源管理对象都有一个refCount字段,共享一个资源的资源管理对象的refCount取值一样,但是怎么保持一致呢?因为这些对象之间没有关联。同时注意:这里不能把refCount字段声明为static,因为static意味着资源管理类的所有对象共享refCount,而当前的要求是一部分对象共享一个refCount,另一部分对象共享另一个refCount。因此,引用计数要和资源绑定在一起。也就是说,这里需要两层封装:第一层是u_ptr<T>类,对资源封装,增加refCount字段,负责delete。第二层是shared_ptr<T>,对u_ptr<T>封装,判断u_ptr对象的引用计数为0,执行u_ptr的析构方法,间接释放资源。

4、有些情况下,当引用计数为0 的时候,我们不想执行delete,而是其他操作,因此,还需要一个删除器,和引用计数同样的道理,删除器应该放在u_ptr中,这个删除器就是指向方法的指针。

5、auto_ptr的copy构造和copy赋值,要转移拥有权。而shared_ptr的copy构造,引用计数加1,copy赋值对原对象的引用计数减1,引用计数为0,执行delete,同时对rhs的引用计数加1。

6、析构的时候,引用计数减1,引用计数为0,才执行delete。

7、示例代码如下(不完整,只有一部分):

 1 template <typename T>
 2 class u_ptr
 3 {
 4  template <typename T> friend class shared_ptr;  
 5 private:
 6  u_ptr(T* ptr):_ptr(ptr),refCount(1)
 7  {
 8  }
 9 
10  ~u_ptr()
11  {
12   delete _ptr;  
13  }
14 
15  T* _ptr;
16  int refCount;
17 };
18 
19 template <typename T>
20 class shared_ptr
21 {
22 public:
23  shared_ptr(T* ptr):_u_ptr_ptr(new u_ptr<T>(ptr))
24  {
25  }
26 
27  shared_ptr(shared_ptr<T>& rhs)
28  {
29   _u_ptr_ptr= rhs._u_ptr_ptr;
30   ++_u_ptr_ptr->refCount;
31  }
32 
33  shared_ptr& operator=(shared_ptr<T>& rhs)
34  {
35   if(this!=&rhs)
36   {
37    if(--_u_ptr_ptr->refCount ==0)
38    {
39     delete _u_ptr_ptr;
40    }
41    _u_ptr_ptr= rhs._u_ptr_ptr;
42    ++_u_ptr_ptr->refCount; 
43   }
44   return *this;
45  }
46 
47  ~shared_ptr()
48  {
49   if(--_u_ptr_ptr->refCount ==0)
50   {
51    delete _u_ptr_ptr;
52   }
53  }
54 
55 private:
56  u_ptr<T>* _u_ptr_ptr;
57 };
原文地址:https://www.cnblogs.com/nzbbody/p/3524508.html