智能指针--scoped_ptr shared_ptr weak_ptr

所谓智能指针就是智能/自动化的管理指针所指向的动态资源的释放;

scopde_ptr--防拷贝

什么叫做防拷贝?就是不允许一个地址空间的指针赋值给另一个指针,导致有两个指针指向同一个地址;也就是说防拷贝能保证地址与指针是一一对应的关系;

实现方法:要拷贝,就需要通过对象来调用赋值运算符重载函数/拷贝构造函数,只要将这两个成员函数私有化/保护化,就ok啦;

具体代码:

 

template<class T>
class ScopedePtr
{
public:
	ScopedePtr(T *ptr)
		:_ptr(ptr)
	{}
	~ScopedePtr()
	{
		delete _ptr;
	}

	T* GetPtr()
	{
		return _ptr;
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
protected:
	ScopedePtr<T>& operator=(const ScopedePtr<T> &sp);
	ScopedePtr(const ScopedePtr<T> &sp);

protected:
	T *_ptr;
};
shared_ptr--引用计数

允许多个指向同一块地址;每增加一个指向该地址的指针计数器就加一;减少一个指向该地址的指针计数器减一,直到计数器的值为0的时候进行delete释放这块空间;

代码:

template<class T>
class SharedPtr
{
	SharedPtr(T * ptr)
	:_ptr(ptr)
	, _ptrCount(new int(1))
	{
	}
	~SharedPtr()
	{
		if (*_ptrCount == 0)
		{
			delete _ptr;
		}
	}

	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}

	SharedPtr<T>& operator=(const SharedPtr<T>& sp)
	{
		Release();
		_ptr = sp._ptr;
		_ptrCount = sp._ptrCount;
		(*_ptrCount)++;
	}

	SharedPtr(const SharedPtr<T>& sp)
		:_ptr(sp._ptr)
	{
		_ptrCount = sp._ptrCount;
		(*_ptrCount)++;
	}

	void Release()
	{
		if (*_ptrCount != 0)
			(*_ptrCount)--;
	}

protected:
	T *_ptr;
	int *_ptrCount;
};
但是share_ptr有一个循环引用的问题:


当在双向链表时,想要释放p1但是p2->_prev指向p1,引用计数为1,想要释放p1必须先释放p2;对于p2而言想要释放也必须先释放p1;这就构成了循环引用问题,两者都不能释放;

weak_ptr就应运而生,专们用来辅助shared_ptr;

weak_ptr对象引用资源时不会增加引用计数,但是它能够通过lock()方法来判断它所管理的资源是否被释放。另外很自然地一个问题是:既然weak_ptr不增加资源的引用计数,那么在使用weak_ptr对象的时候,资源被突然释放了怎么办呢?呵呵,答案是你根本不能直接通过weak_ptr来访问资源。那么如何通过weak_ptr来间接访问资源呢?答案是:在需要访问资源的时候weak_ptr为你生成一个shared_ptr,shared_ptr能够保证在shared_ptr没有被释放之前,其所管理的资源是不会被释放的。创建shared_ptr的方法就是lock()方法。

弱指针当引用的对象活着的时候不一定存在。仅仅是当它存在的时候的一个引用。弱指针并不修改该对象的引用计数,这意味这弱指针它并不对对象的内存进行管理,在功能上类似于普通指针,然而一个比较大的区别是,弱指针能检测到所管理的对象是否已经被释放,从而避免访问非法内存

template<typename T> class weak_ptr {
    public:
        template <typename Y>
        weak_ptr(const shared_ptr<Y>& r);

        weak_ptr(const weak_ptr& r);

        ~weak_ptr();

        T* get() const; 
        bool expired() const; 
        shared_ptr<T> lock() const;
    };
expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用指针。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值