1、引用计数字段不能放在资源管理类中。我们的解决办法是,把引用计数和资源绑在一起,进行二次封装。但是这样存在一个大问题,不同类型的资源管理类不能兼容。也就是说,shared_ptr<Dog>不能赋值给shared_ptr<Animal>。
2、你可能会想,使用模版成员方法去解决,但是这里有个问题。因为进行了两次封装,u_ptr的类型还是不一样,也不能赋值。你可能会想,我在u_ptr中也建立模版成员方法,这也是错的。思考下,我们要保证,资源管理类指向同一个u_ptr,对u_ptr进行拷贝,那么资源管理类就不是指向同一个u_ptr了,这显然是错的。
3、有没有其它的办法呢?
问题的关键是,进行了两次封装。不进行两次封装就好了,为了保证资源管理类指向同一个资源,同时指向同一个引用计数值,我可以再建立一个int指针,指向引用计数。
4、示例代码:
1 template <typename T> 2 class shared_ptr_2 3 { 4 public: 5 shared_ptr_2(T* ptr):_ptr(ptr),_refCount_ptr(new int(1)) 6 { 7 } 8 9 shared_ptr_2(shared_ptr_2<T>& rhs) 10 { 11 _ptr= rhs._ptr; 12 _refCount_ptr = rhs._refCount_ptr; 13 ++(*_refCount_ptr); 14 } 15 16 template <typename U> 17 shared_ptr_2<T>(shared_ptr_2<U>& rhs) 18 { 19 _ptr = rhs._ptr; 20 _refCount_ptr = rhs._refCount_ptr; 21 ++(*_refCount_ptr); 22 } 23 24 shared_ptr_2& operator=(shared_ptr_2<T>& rhs) 25 { 26 if(this!=&rhs) 27 { 28 if(--(*_refCount_ptr) ==0) 29 { 30 delete _ptr; 31 delete _refCount_ptr; 32 } 33 _ptr= rhs._ptr; 34 _refCount_ptr = rhs._refCount_ptr; 35 ++(*_refCount_ptr); 36 } 37 return *this; 38 } 39 40 template <typename U> 41 shared_ptr_2<T>& operator=(shared_ptr_2<U>& rhs) 42 { 43 ++(*_refCount_ptr); 44 if(--(*_refCount_ptr) ==0) 45 { 46 delete _ptr; 47 delete _refCount_ptr; 48 } 49 _ptr= rhs._ptr; 50 _refCount_ptr = rhs._refCount_ptr; 51 return *this; 52 } 53 54 ~shared_ptr_2() 55 { 56 if(--(*_refCount_ptr) ==0) 57 { 58 delete _ptr; 59 delete _refCount_ptr; 60 } 61 } 62 63 private: 64 T* _ptr; 65 int* _refCount_ptr; 66 67 friend class shared_ptr_2; 68 };