[c++]智能指针的实现

智能指针最基本的概念是引用计数,也就是智能指针内部有一个计数器,记录了当前内存资源到底有多少指针在引用(可以访问这个资源),当新增加一个可以访问这个资源的引用时,计数器会加1,反之会减去1,当计数器为0时,智能指针会自动释放他所管理的资源。手动申请,自动释放,就是其智能的体现。

模拟auto_ptr

先看看库里的解释

auto_ptr

template<class T>
    class auto_ptr {
public:
    typedef T element_type;
    explicit auto_ptr(T *p = 0) throw();
    auto_ptr(const auto_ptr<T>& rhs) throw();
    auto_ptr<T>& operator=(auto_ptr<T>& rhs) throw();
    ~auto_ptr();
    T& operator*() const throw();
    T *operator->() const throw();
    T *get() const throw();
    T *release() const throw();
    };

The class describes an object that stores a pointer to an allocated object of type T. The stored pointer must either be null or designate an object allocated by a new expression. The object also stores an ownership indicator. An object constructed with a non-null pointer owns the pointer. It transfers ownership if its stored value is assigned to another object. The destructor for auto_ptr<T> deletes the allocated object if it owns it. Hence, an object of class auto_ptr<T> ensures that an allocated object is automatically deleted when control leaves a block, even via a thrown exception.

后面的英语看不懂,反正就是实现上面的声明函数;如下(以下代码均用类模版实现)

template<typename T>
class AutoPtr
{
public:
	AutoPtr()
		:_ptr(new int(1))
	{}
	~AutoPtr()
	{
		delete _ptr;
		_ptr=NULL;
	}
	AutoPtr( AutoPtr<T>& ap)
	{
		_ptr=ap._ptr;
		ap._ptr=NULL;
	}
	AutoPtr<T>& operator=(AutoPtr<T>& ap)
	{
		delete _ptr;
		_ptr=ap._ptr;
		ap._ptr=NULL;
		return *this;
	}
	T* operator->()
	{
		return _ptr;
	}
	T& operator*()
	{
		return *_ptr;
	}
private:
	T* _ptr;
};
void AutoPtrTest()
{
	AutoPtr<int> ap1;
	*ap1=10;
	AutoPtr<int> ap2(ap1);
	AutoPtr<int> ap3=ap1;
  cout<<*ap1<<endl;
  cout<<*ap2<<endl;
  cout<<*ap3<<endl;
}
模拟实现scoped_ptr

scoped_ptr智能指针与std::auto_ptr不同,因为它是不传递所有权的。事实上它明确禁止任何想要这样做的企图!

template<typename T>
class ScopePtr
{
public:
	ScopePtr()
		:_ptr(new int(1))
	{}
	~ScopePtr()
	{
		delete _ptr;
		_ptr=NULL;
	}
	T& operator *()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
protected:
	ScopePtr(const ScopePtr<T>& sp);
	ScopePtr<T>& operator=(const ScopePtr<T>& sp);
private:
	T* _ptr;
};
void ScopePtrTest()
{
	ScopePtr<int> sp1;
    *sp1=1;
	cout<<*sp1<<endl;
}


模拟实现Share_ptr

template <typename T>
class SharedPtr {
public:
	SharedPtr():
	  p(NULL)
		  , pCount(new int(1)) 
	  { }
	  explicit SharedPtr(T *pt)
		  : p(pt)
		  , pCount(new int(1)) 
	  {    }
	  SharedPtr(const SharedPtr &sp)
		  : p(sp.p)
		  , pCount(sp.pCount) 
	  { 
		  if (pCount) 
			  ++*pCount;
	  }
	  SharedPtr& operator=(const SharedPtr&);
	  ~SharedPtr();
	  T& operator*() 
	  { 
		  return *p; 
	  }
	  const T& operator*() const 
	  { 
		  return *p;
	  }
private:
	T *p;
	int *pCount;
};

template <typename T>
SharedPtr<T>::~SharedPtr()
{
	if (pCount && 0 == --*pCount)
	{
		delete p;   
		delete pCount;
	}
}
void SharedPtrTest()
{
	SharedPtr<int> sp1(new int(1));
	SharedPtr<int> sp2(sp1);
	SharedPtr<int> sp3=sp1;
	cout<<*sp1<<endl;
	cout<<*sp2<<endl;
	cout<<*sp3<<endl;
        cout<<sp1.pCount<<endl;
<pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 24px;">        cout<<sp2.pCount<<endl;
        cout<<sp3.pCount<<endl;
}

 
这里有一个你在标准库中找不到的—引用数智能指针。大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章。最重要的一个细节是引用数是如何被执行的—插入,意思是说你将 
引用计数 
的功能添加给类,或者是非插入,意思是说你不这样做。Boost shared_ptr是非插入类型的,这个实现使用一个从堆中分配来的 
引用计数 
器。关于提供参数化策略使得对任何情况都极为适合的讨论很多了,但是最终讨论的结果是决定反对聚焦于可用性。可是不要指望讨论的结果能够结束。 

shared_ptr完成了你所希望的工作:他负责在不使用实例时删除由它指向的对象(pointee),并且它可以自由的共享它指向的对象



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值