C++源码—_Ptr_base(MSVC 2017)

1 _Ptr_base

_Ptr_base 是智能指针的基类,它包含两个成员变量:指向目标元素的指针 _Ptr 和 引用计数基类指针 _Rep

private:
	element_type * _Ptr{nullptr};  
	_Ref_count_base * _Rep{nullptr}; 

 


 

1.1 element_type * _Ptr

_Ptr 指向的元素类型为 using element_type = remove_extent_t<_Ty>,remove_extent_t 会移除类型中的数组,如果类型是多维数组,则只移除第一维。

int a, b[3];
typeid(remove_extent<int>::type) == typeid(a);  //true
typeid(remove_extent<int[]>::type) == typeid(a);  //true
typeid(remove_extent<int[][3]>::type) == typeid(a); //flase
typeid(remove_extent<int[][3]>::type) == typeid(b); //true    

 


 

1.2 _Ref_count_base * _Rep

_Ref_count_base 是引用计数基类,它包含两个成员变量:原子计数器 _Uses 和 弱引用计数 _Weaks

 

_MT_INCR 和 _MT_DECR 是宏定义,实现原子操作。

#define _MT_INCR(x)  _InterlockedIncrement(reinterpret_cast<volatile long *>(&x))
#define _MT_DECR(x)  _InterlockedDecrement(reinterpret_cast<volatile long *>(&x))

 

当 _Uses 为 0 时,调用 _Destroy() 释放对象;当 _Weaks 为 0 时,调用 _Delete_this() 释放 _Ref_count_base。此外就是一些引用计数的增加、减少等函数的实现。

class __declspec(novtable) _Ref_count_base
	{	// common code for reference counting
private:
#ifdef _M_CEE_PURE
	virtual void _Destroy() noexcept
		{	// permanent workaround to avoid mentioning _purecall in msvcurt.lib, ptrustu.lib, or other support libs
		_STD terminate();
		}

	virtual void _Delete_this() noexcept
		{	// permanent workaround to avoid mentioning _purecall in msvcurt.lib, ptrustu.lib, or other support libs
		_STD terminate();
		}
#else /* ^^^ _M_CEE_PURE ^^^ // vvv !_M_CEE_PURE vvv */
	virtual void _Destroy() noexcept = 0;
	virtual void _Delete_this() noexcept = 0;
#endif /* _M_CEE_PURE */

	_Atomic_counter_t _Uses;  //原子计数器, unsigned long
	_Atomic_counter_t _Weaks;  //弱引用计数

protected:
	_Ref_count_base()
		: _Uses(1), _Weaks(1)	// non-atomic initializations
		{	// construct
		}

public:
	virtual ~_Ref_count_base() noexcept
		{	// TRANSITION, should be non-virtual
		}

	bool _Incref_nz()
		{	// increment use count if not zero, return true if successful
		for (;;)
			{	// loop until state is known
 #if _USE_INTERLOCKED_REFCOUNTING
			const _Atomic_integral_t _Count =
				static_cast<volatile _Atomic_counter_t&>(_Uses);

			if (_Count == 0)
				return (false);

			if (static_cast<_Atomic_integral_t>(_InterlockedCompareExchange(
					reinterpret_cast<volatile long *>(&_Uses),
					static_cast<long>(_Count + 1), static_cast<long>(_Count))) == _Count)
				return (true);

 #else /* _USE_INTERLOCKED_REFCOUNTING */
			const _Atomic_integral_t _Count =
				_Load_atomic_counter(_Uses);

			if (_Count == 0)
				return (false);

			if (_Compare_increment_atomic_counter(_Uses, _Count))
				return (true);
 #endif /* _USE_INTERLOCKED_REFCOUNTING */
			}
		}

	void _Incref()
		{	// increment use count
		_MT_INCR(_Uses);
		}

	void _Incwref()
		{	// increment weak reference count
		_MT_INCR(_Weaks);
		}

	void _Decref()
		{	// decrement use count
		if (_MT_DECR(_Uses) == 0)
			{	// destroy managed resource, decrement weak reference count
			_Destroy();
			_Decwref();
			}
		}

	void _Decwref()
		{	// decrement weak reference count
		if (_MT_DECR(_Weaks) == 0)
			{
			_Delete_this();
			}
		}

	long _Use_count() const noexcept
		{	// return use count
		return (static_cast<long>(_Get_atomic_count(_Uses)));
		}

	virtual void * _Get_deleter(const type_info&) const noexcept
		{	// return address of deleter object
		return (nullptr);
		}
	};

  


 

1.3 成员函数

template<class _Ty>
	class _Ptr_base
	{	// base class for shared_ptr and weak_ptr
public:
	using element_type = remove_extent_t<_Ty>;

	_NODISCARD long use_count() const noexcept
		{	// return use count
		return (_Rep ? _Rep->_Use_count() : 0);
		}

	template<class _Ty2>
		_NODISCARD bool owner_before(const _Ptr_base<_Ty2>& _Right) const noexcept
		{	// compare addresses of manager objects
		return (_Rep < _Right._Rep);
		}

	_Ptr_base(const _Ptr_base&) = delete;
	_Ptr_base& operator=(const _Ptr_base&) = delete;

protected:
	_NODISCARD element_type * get() const noexcept
		{	// return pointer to resource
		return (_Ptr);
		}

	constexpr _Ptr_base() noexcept = default;

	~_Ptr_base() = default;

	template<class _Ty2>
		void _Move_construct_from(_Ptr_base<_Ty2>&& _Right)
		{	// implement shared_ptr's (converting) move ctor and weak_ptr's move ctor
		_Ptr = _Right._Ptr;
		_Rep = _Right._Rep;

		_Right._Ptr = nullptr;
		_Right._Rep = nullptr;
		}

	template<class _Ty2>
		void _Copy_construct_from(const shared_ptr<_Ty2>& _Other)
		{	// implement shared_ptr's (converting) copy ctor
		if (_Other._Rep)
			{
			_Other._Rep->_Incref();
			}

		_Ptr = _Other._Ptr;
		_Rep = _Other._Rep;
		}

	template<class _Ty2>
		void _Alias_construct_from(const shared_ptr<_Ty2>& _Other, element_type * _Px)
		{	// implement shared_ptr's aliasing ctor
		if (_Other._Rep)
			{
			_Other._Rep->_Incref();
			}

		_Ptr = _Px;
		_Rep = _Other._Rep;
		}

	template<class _Ty0>
		friend class weak_ptr;	// specifically, weak_ptr::lock()

	template<class _Ty2>
		bool _Construct_from_weak(const weak_ptr<_Ty2>& _Other)
		{	// implement shared_ptr's ctor from weak_ptr, and weak_ptr::lock()
		if (_Other._Rep && _Other._Rep->_Incref_nz())
			{
			_Ptr = _Other._Ptr;
			_Rep = _Other._Rep;
			return (true);
			}

		return (false);
		}

	void _Decref()
		{	// decrement reference count
		if (_Rep)
			{
			_Rep->_Decref();
			}
		}

	void _Swap(_Ptr_base& _Right) noexcept
		{	// swap pointers
		_STD swap(_Ptr, _Right._Ptr);
		_STD swap(_Rep, _Right._Rep);
		}

	void _Set_ptr_rep(element_type * _Other_ptr, _Ref_count_base * _Other_rep)
		{	// take new resource
		_Ptr = _Other_ptr;
		_Rep = _Other_rep;
		}

	template<class _Ty2>
		void _Weakly_construct_from(const _Ptr_base<_Ty2>& _Other)
		{	// implement weak_ptr's ctors
		if (_Other._Rep)
			{
			_Other._Rep->_Incwref();
			}

		_Ptr = _Other._Ptr;
		_Rep = _Other._Rep;
		}

	void _Decwref()
		{	// decrement weak reference count
		if (_Rep)
			{
			_Rep->_Decwref();
			}
		}

private:
	element_type * _Ptr{nullptr};  //指向目标元素
	_Ref_count_base * _Rep{nullptr};  //引用计数基类指针

	template<class _Ty0>
		friend class _Ptr_base;

#if _HAS_STATIC_RTTI
	template<class _Dx,
		class _Ty0>
		friend _Dx * get_deleter(const shared_ptr<_Ty0>& _Sx) noexcept;
#endif /* _HAS_STATIC_RTTI */
	};

  

 

posted @ 2022-03-09 20:00  Kayden_Cheung  阅读(107)  评论(0编辑  收藏  举报
//目录