c++11之weak_ptr剖析

一、概述

     引用《c++ primer》的话:weak_ptr是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。

将一个weak_ptr绑定到shared_ptr不会改变shared_ptr的引用计数【0】。一旦最后一个指向对象的shared_ptr被销毁,对象

就会被释放。即使有weak_ptr指向对象,对象也会被释放。

    weak_ptr与shared_ptr继承同一个基类 _Ptr_base 因此有一样的资源指针字段、计数器字段。但是其“关注点”不一样。接下来通过源码了解一下weak_ptr构造、析构过程。

二、源码分析

     1. weak_ptr构造

    //[0]构造函数
    template         class = typename enable_if::value,
            void>::type>
        weak_ptr(const shared_ptr<_Ty2>& _Other) _NOEXCEPT
        {    // construct weak_ptr object for resource owned by _Other
        this->_Resetw(_Other);
        }
        
//[1]调用基类构造,与shared_ptr继承同一个基类。
constexpr _Ptr_base() _NOEXCEPT
    : _Ptr(0), _Rep(0)
    {    
      // construct
    }
    
//[2]执行构造函数体调用如下函数,实参为传入的shared_ptr对象
template
    void _Resetw(const _Ptr_base<_Ty2>& _Other)
    {    // release weak reference to resource and take _Other._Ptr
        //[3]传入shared_ptr的引用计数器,资源指针
       _Resetw(_Other._Ptr, _Other._Rep);
    }
//[3]
template
    void _Resetw(_Ty2 *_Other_ptr, _Ref_count_base *_Other_rep)
    {    // point to _Other_ptr through _Other_rep
          if (_Other_rep)
               _Other_rep->_Incwref(); //[4] 递增传入shared_ptr对象的weak计数。
          if (_Rep != 0)
               _Rep->_Decwref();
          //[5]weak对象共享shared_ptr的数据指针、计数器。
          _Rep = _Other_rep;
           _Ptr = const_cast *>(_Other_ptr);
    }

    概述中【0】那句话所陈述的含义已经有解释依据即代码段中注释[4]。

    weak_ptr与与之绑定的shared_ptr共享资源和计数器。

2.weak_ptr析构       

~weak_ptr() _NOEXCEPT
    {    // release resource
    this->_Decwref();【1】
    }
    
//[1]递减weak计数
void _Decwref()
    {    // decrement weak reference count
    if (_Rep != 0)
        _Rep->_Decwref(); //[2]将共享的计数器中weak进行递减。
    }
//[2]_Ref_count 成员,如果Weak-1为0将释放计数器
void _Decwref()
{    // decrement weak reference count
if (_MT_DECR(_Weaks) == 0)
    _Delete_this(); //[3]
}

//[3]_Ref_count成员
virtual void _Delete_this() _NOEXCEPT
{    
    // destroy self
    delete this;
}

weak_ptr析构会递减共享计数器的weaks字段。因此不会更改引用计数(uses)。

weaks字段另外一个作用就是指示weak_ptr对象是否还存在,若weak_ptr对象都没有了, 引用计数器才可以释放。

你可能感兴趣的:(boost,库与stl,weak_ptr)