shared_ptr是从C++11开始提供的智能指针,用于管理多个指针对同一实体的资源释放问题,保证在多个指针指向同一实体时,仅最后一个指针解除指向时才会释放资源。
shared_ptr构造
shared_ptr<_Tp>继承自__shared_ptr<_Tp>,其功能主要由其实现。让我们以单值构造函数为切入点开始分析。
template<typename _Yp, typename = _Constructible<_Yp*>>
explicit
shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) {
}
从中我们可以看到,调用了基类的构造函数,定义如下
template<typename _Yp, typename = _SafeConv<_Yp>>
explicit
__shared_ptr(_Yp* __p)
: _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
{
static_assert( !is_void<_Yp>::value, "incomplete type" );
static_assert( sizeof(_Yp) > 0, "incomplete type" );
_M_enable_shared_from_this_with(__p);
}
其初始化了成员变量_M_ptr
和_M_refcount
,这两个成员变量的定义如下。element_type
就是构造时传入的指针指向类型,这里我们可以看到,share_ptr的实现就是最基本的指针加上引用计数。
element_type* _M_ptr; // Contained pointer.
__shared_count<_Lp> _M_refcount; // Reference counter.
让我们接下看看_M_refcount
的构造过程,其调用如下构造函数,我们能够看到他初始化了数据成员_M_pi
。
template<typename _Ptr>
explicit
__shared_count(_Ptr __p) : _M_pi(0)
{
__try
{
_M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
}
__catch(...)
{
delete __p;
__throw_exception_again;
}
}
数据成员_M_pi的定义如下,他是一个基类的指针,可以指向任何派生类,所以_M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p)
并不存在任何语法问题。
_Sp_counted_base<_Lp>* _M_pi;
让我们接着查看代码,首先是_Sp_counted_ptr<_Ptr, _Lp>(__p)
的构造,其初始化了数据成员_Ptr _M_ptr
,这里我们可以发现_Sp_counted_ptr
存在一个指针指向其引用的对象。
explicit
_Sp_counted_ptr(_Ptr __p) noexcept