C++智能指针shared_ptr的实现

shared_ptr的实现

智能指针对象中引用计数是多个智能指针对象共享的,两个线程中智能指针的引用计数同时++或–,这个操作不是原子的,引用计数原来是1,++了两次,可能只实际只有一个加生效了,引用计数是2,这样引用计数就错乱了。会导致资源未释放或者程序崩溃的问题。所以只能指针中引用计数++、–是需要加锁的,也就是说引用计数的操作是线程安全的 。

#include <thread> 
#include <mutex> 

template <class T>
class SharedPtr
{
public:
 SharedPtr(T* ptr = nullptr)
  : _ptr(ptr)
  , _pRefCount(new int(1))
  , _pMutex(new mutex)
 {}
 ~SharedPtr() { Release(); }
 SharedPtr(const SharedPtr<T>& sp)
  : _ptr(sp._ptr)
  , _pRefCount(sp._pRefCount)
  , _pMutex(sp._pMutex)
 {
  AddRefCount();
 }
 // sp1 = sp2
 SharedPtr<T>& operator=(const SharedPtr<T>& sp)
 {
  //if (this != &sp)
  if (_ptr != sp._ptr)
  {
   // 释放管理的旧资源
   Release();
   // 共享管理新对象的资源,并增加引用计数
   _ptr = sp._ptr;
   _pRefCount = sp._pRefCount;
   _pMutex = sp._pMutex;
   AddRefCount();
  }
  return *this;
 }
 T& operator*() { return *_ptr; }
 T* operator->() { return _ptr; }
 int UseCount() { return *_pRefCount; }
 T* Get() { return _ptr; }
 void AddRefCount()
 {
  // 加锁或者使用加1的原子操作
  _pMutex->lock();
  ++(*_pRefCount);
  _pMutex->unlock();
 }
private:
 void Release()
 {
  bool deleteflag = false;
  // 引用计数减1,如果减到0,则释放资源
  _pMutex.lock();
  if (--(*_pRefCount) == 0)
  {
   delete _ptr;
   delete _pRefCount;
   deleteflag = true;
  }
  _pMutex.unlock();
  if (deleteflag == true)
   delete _pMutex;
 }
private:
 int* _pRefCount; // 引用计数
 T* _ptr; // 指向管理资源的指针
 mutex* _pMutex; // 互斥锁
};
int main()
{
 SharedPtr<int> sp1(new int(10));
 SharedPtr<int> sp2(sp1);
 *sp2 = 20;
 cout << sp1.UseCount() << endl;
 cout << sp2.UseCount() << endl;
 SharedPtr<int> sp3(new int(10));
 sp2 = sp3;
 cout << sp1.UseCount() << endl;
 cout << sp2.UseCount() << endl;
 cout << sp3.UseCount() << endl;
 sp1 = sp3;
 cout << sp1.UseCount() << endl;
 cout << sp2.UseCount() << endl;
 cout << sp3.UseCount() << endl;
 return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值