C++(20)——弱引用智能指针weak_ptr

前言

在正式介绍weak_ptr之前,我们先来回忆一下shard_ptr的一些知识,我们直到shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个对象,并维护了一个共享的引用计数器。

深入

weak_ptr也是一个引用计数型智能指针,但是它不增加对象的引用计数,即弱引用。与之相对,shared_ptr是强引用,只要有一个指向对象的shared_ptr存在,该对象就不会析构,直到指向对象的最后一个shared_ptr析构或reset()时才会被销毁。

利用weak_ptr,我们可以解决常见的空悬指针问题以及循环引用问题。

weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,也就是将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。
weak_ptr更像是一个助手而不是一个智能指针,它不拥有对动态对象的管辖权。

如何判断weak_ptr指向的对象是否存在?
既然weak_ptr并不改变其所共享的shared_ptr实例的引用计数,那就存在weak_ptr指向的对象被释放调这种可能性,我们就不能使用weak_ptr直接访问对象,那么我们如何判断weak_ptr指向的对象是否存在呢?
C++提供了lock函数来实现该功能,如果对象存在,lock函数返回一个指向共享对象的shared_ptr,否则返回一个空shared_ptr;
C++(20)——弱引用智能指针weak_ptr_第1张图片
如何使用weak_ptr,因为它并没有重载->和*操作符,因此不可以通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr的实例,进而访问原对象:
C++(20)——弱引用智能指针weak_ptr_第2张图片

仿写weak_ptr

template<class _Ty>
class RefCnt
{
public:
	_Ty* _Ptr;               // Obj;
	std::atomic_int _Uses;   // shared_ptr;
	std::atomic_int _Weaks;  // weak_ptr;

public:
	RefCnt(_Ty* p) :_Ptr(p), _Uses(1), _Weaks(1) {}
	~RefCnt() {}
	void _Incref() { _Uses += 1; }
	void _Incwref() { _Weaks += 1; }
};
template<class _Ty> class my_weak_ptr;


template<class _Ty, class _Dx = MyDeletor<_Ty> >
class my_shared_ptr // thread;
{
private:
	_Ty*           _Ptr; // Object;
	RefCnt<_Ty>  * _Rep;
	_Dx _mDeletor;
public:
	my_shared_ptr(_Ty* p = nullptr) :_Ptr(nullptr), _Rep(nullptr)
	{
		if (p != nullptr)
		{
			_Ptr = p;
			_Rep = new RefCnt<_Ty>(p);
		}
	}
	my_shared_ptr(const my_shared_ptr& _Y):_Ptr(_Y._Ptr),_Rep(_Y._Rep)
	{
		if (_Rep != nullptr)
		{
			_Rep->_Incref(); // _Uses
		}
	}
	my_shared_ptr(my_shared_ptr&& other):_Ptr(other._Ptr),_Rep(other._Rep)
	{
		other._Ptr = nullptr;
		other._Rep = nullptr;
	}
	my_shared_ptr& operator=(const my_shared_ptr& r)
	{
		if (this == &r || this->_Ptr == r._Ptr) return *this;
		if (_Ptr != nullptr && --_Rep->_Uses == 0)
		{
			_mDeletor(_Ptr);
			if (--_Rep->_Weaks == 0)
			{
				delete _Rep;
			}
		}
		_Ptr = r._Ptr;
		_Rep = r._Rep;
		if (_Ptr != nullptr)
		{
			_Rep->_Incref(); // _Uses;
		}
		return *this;
	}
	my_shared_ptr& operator=(my_shared_ptr&& other)
	{
		if (this == &other) return *this;
		if (_Ptr != nullptr && other._Ptr != nullptr && _Ptr == other._Ptr)
		{//共享同一资源的移动构造
			this->_Rep->_Uses -= 1;
			other._Ptr = nullptr;
			other._Rep = nullptr;
			return *this;
		}
        //指向不同对象
		if (_Ptr != nullptr && --_Rep->_Uses == 0)
		{
			_mDeletor(_Ptr);
			if (--_Rep->_Weaks == 0)
			{
				delete _Rep;
			}
		}
		_Ptr = other._Ptr;
		_Rep = other._Rep;
		other._Ptr = nullptr;
		other._Rep = nullptr;
		return *this;
	}
	~my_shared_ptr()
	{
		if (_Rep != nullptr && --_Rep->_Uses == 0)
		{
			_mDeletor(_Ptr);//删除所管理的对象
			if (--_Rep->_Weaks == 0)
			{
				delete _Rep;//删除Refcnt
			}
		}
		_Ptr = nullptr;
		_Rep = nullptr;
	}

	_Ty* get() const { return _Ptr; }
	_Ty& operator*() const { return *get(); }
	_Ty* operator->() const { return get(); }
	size_t use_count() const
	{
		if (_Rep == nullptr) return 0;
		return _Rep->_Uses;
	}
	void swap(my_shared_ptr& r)
	{
		std::swap(_Ptr, r._Ptr);
		std::swap(_Rep, r._ref);
	}
	operator bool() const { return _Ptr != nullptr; }

	template<class _Ty>
	friend class my_weak_ptr;
};


template<class _Ty>
class my_weak_ptr
{
private:
	RefCnt<_Ty>* _Rep;
public:
	my_weak_ptr() :_Rep(nullptr) {}
	my_weak_ptr(const my_shared_ptr<_Ty>& other):_Rep(other._Rep)
	{
		if (_Rep != nullptr)
		{
			_Rep->_Incwref(); // Weaks;
		}
	}
	my_weak_ptr(const my_weak_ptr& other):_Rep(other._Rep)
	{
		if (_Rep != nullptr)
		{
			_Rep->_Incwref();
		}
	}
	my_weak_ptr(my_weak_ptr&& other):_Rep(other._Rep)
	{
		other._Rep = nullptr;
	}
	my_weak_ptr& operator=(const my_weak_ptr& other)
	{
		if (this == &other || this->_Rep == other._Rep) return *this;
		if (_Rep != nullptr && --_Rep->_Weaks == 0)
		{
			delete _Rep;
		}
		_Rep = other->_Rep;
		if (_Rep != nullptr)
		{
			_Rep->_Incwref();
		}
		return *this;
	}
	my_weak_ptr& operator=(my_weak_ptr&& other)
	{
		if (this == &other) return *this;
		if (this->_Rep != nullptr && other._Rep != nullptr && _Rep == other._Rep)
		{
			this->_Rep->_Weaks -= 1;
			other._Rep = nullptr;
			return *this;
		}
		if (_Rep != nullptr && --_Rep->_Weaks == 0)
		{
			delete _Rep;
		}
		_Rep = other._Rep;
		other._Rep = nullptr;
		return *this;
	}
	my_weak_ptr& operator=(const my_shared_ptr<_Ty>& other)
	{
		if (_Rep != nullptr && --_Rep->_Weaks == 0)
		{
			delete _Rep;
		}
		_Rep = other._Rep;
		if (_Rep != nullptr)
		{
			_Rep->_Incwref();
		}
		return *this;
	}

	//弱指针不拥有资源,只是检测Ref结构是否存在
	my_weak_ptr& operator=(my_shared_ptr<_Ty>&& other) = delete;

	~my_weak_ptr()
	{
		if (_Rep != nullptr && --_Rep->_Weaks == 0)
		{
			delete _Rep;
		}
		_Rep = nullptr;
	}
	//检查被引用的对象是否删除
	bool expired() const
	{
		return this->_Rep->_Uses == 0;
	}
	//创建一个shared_ptr管理被引用对象
	my_shared_ptr<_Ty> lock() const
	{
		my_shared_ptr<_Ty> _Ret;
		_Ret._Ptr = _Rep->_Ptr;
		_Ret._Rep = _Rep;
		_Ret._Rep->_Incref();
		return _Ret;
	}
};

你可能感兴趣的:(c++,c++,objective-c,开发语言)