• 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 */
    	};
    

      

  • 相关阅读:
    linux学习(一)
    Linux学习(用户管理)
    anyproxy mac安装
    python mitmproxy 代理
    Js常用方法map, sort
    echarts常用配置项【持续更新】
    【转】moment js 使用
    js Cannot assign to read only property 'exports' of object '#<Object>' at Modul,import 与module.exports混用问题
    a标签跳转referer漏洞
    element ui rate评分组建使用
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/15986051.html
Copyright © 2020-2023  润新知