shared_ptr智能指针源码分析

shared_ptr智能指针源码分析

1 先写应用代码

#include <iostream>
#include <memory>
int main()
{
	std::shared_ptr<int> sptr(new int(42));
	// sptr1 = std::make_shared<int>(32);
	std::shared_ptr<int> sp2 = sptr;
	std::weak_ptr<int >wptr;
	wptr = sptr;
	std::cout << "Hello World!\n";
}

2 查看源码

shared_ptr和weak_ptr都继承于基类_Ptr_base,基类里有原始指针_Ptr和计数类指针*Rep。*
_Ref_count_base计数类是虚基类。有2个纯虚函数和强弱指针的 计数:
virtual void _Destroy() noexcept = 0;
virtual void _Delete_this() noexcept = 0;
_Atomic_counter_t _Uses;//强指针次数
_Atomic_counter_t _Weaks;//弱指针次数
_Ref_count实现其虚函数。
_Ref_count有其独有的指针: _Ty * _Ptr;//内部指针

在这里插入图片描述

3 单步调试

进入 memory文件里std::shared_ptr定义
查看引用shared_ptr的代码,找到shared_ptr构造函数:

	template<class _Ux,
		enable_if_t<conjunction_v<conditional_t<is_array_v<_Ty>, _Can_array_delete<_Ux>, _Can_scalar_delete<_Ux>>,
			_SP_convertible<_Ux, _Ty>>, int> = 0>
		explicit shared_ptr(_Ux * _Px)
		{	// construct shared_ptr object that owns _Px
		_Setp(_Px, is_array<_Ty>{});
		}

设置断点调试f11进入
要构造函数需要先进入基类的构造函数,
程序进入到std::_Ptr_base<_Ty0>
初始化类成员
原始指针 element_type * _Ptr{nullptr};


private:
	element_type * _Ptr{nullptr};//原始指针
	_Ref_count_base * _Rep{nullptr};

首先 构造 计数器 类 new _Ref_count<_Ux>(_Px)
计数器 类_Ref_count可以看出继承于虚基类_Ref_count_base

template<class _Ty>
	class _Ref_count
		: public _Ref_count_base
	{	// handle reference counting for pointer without deleter
public:
	explicit _Ref_count(_Ty * _Px)
		: _Ref_count_base(), _Ptr(_Px)
		{	// construct
		}

private:
	virtual void _Destroy() noexcept override
		{	// destroy managed resource
		delete _Ptr;
		}

	virtual void _Delete_this() noexcept override
		{	// destroy self
		delete this;
		}

	_Ty * _Ptr;
	};

进入虚基类_Ref_count_base
_Ref_count_base()
: _Uses(1), _Weaks(1) // non-atomic initializations
{ // construct
}
_Atomic_counter_t _Uses;//强指针次数
_Atomic_counter_t _Weaks;//弱指针次数
初始化 _Uses(1), _Weaks(1) 指针次数为1

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;
	_Atomic_counter_t _Weaks;

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

public:};

再F11 进入 shared_ptr 构造函数里调用的 成员函数_Setp

	template<class _Ux>
		void _Setp(_Ux * _Px, false_type)
		{	// take ownership of _Px
		_TRY_BEGIN	// allocate control block and set
		_Set_ptr_rep_and_enable_shared(_Px, new _Ref_count<_Ux>(_Px));
		_CATCH_ALL	// allocation failed, delete resource
		delete _Px;
		_RERAISE;
		_CATCH_END
		}

继续F11 执行 _Set_ptr_rep_and_enable_shared(_Px, new _Ref_count<_Ux>(_Px));

进入 shared_ptr 成员函数 _Set_ptr_rep_and_enable_shared

	template<class _Ux>
		void _Set_ptr_rep_and_enable_shared(_Ux * _Px, _Ref_count_base * _Rx)
		{	// take ownership of _Px
		this->_Set_ptr_rep(_Px, _Rx);
		_Enable_shared_from_this(*this, _Px);
		}

进入this->_Set_ptr_rep(_Px, _Rx);
shared_ptr 未重写 _Set_ptr_rep,因此进入基类_Ptr_base的成员函数_Set_ptr_rep

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

进入_Enable_shared_from_this

template<class _Other,
	class _Yty>
	void _Enable_shared_from_this(const shared_ptr<_Other>& _This, _Yty * _Ptr)
	{	// possibly enable shared_from_this
	_Enable_shared_from_this1(_This, _Ptr, bool_constant<conjunction_v<
		negation<is_array<_Other>>,
		negation<is_volatile<_Yty>>,
		_Can_enable_shared<_Yty>>>{});
	}

继续运行 std::shared_ptr sp2 = sptr;//拷贝构造
当有其他强指针指向时,强指针计数增加
在这里插入图片描述
调用shared_ptr的拷贝构造,构建拥有与_Other相同资源的shared_ptr对象。这里是构建sp2,使其拥有和sptr一样的资源。

	shared_ptr(const shared_ptr& _Other) noexcept
		{	// construct shared_ptr object that owns same resource as _Other
		this->_Copy_construct_from(_Other);
		}

拷贝构造的实现:实现shared_ptr的(转换)复制ctor
其实就是 _Ptr_base的成员变量 原始指针和计数的复制 并无再分配空间 (unique指针是禁止了拷贝构造 )

	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;
		}

运行最后减少计数 析构摧毁资源 销毁被管理的资源,减去弱引用计数
_Ref_count_base::_Decref()

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

_Ref_count ::_Destroy() 删除原始指针占用的资源

private:
	virtual void _Destroy() noexcept override
		{	// destroy managed resource
		delete _Ptr;
		}

4 总结

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值