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

      

  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/15986051.html
Copyright © 2020-2023  润新知