tr1中的智能指针详解及使用示例(Rev)

在C++98中,我们已经有了auto_ptr(在头文件memory中)用于对资源的管理,但由于auto_ptr自身的局限制,使得auto_ptr的使用受到很大的限制,并且带来一系列“诡异”的bug,
究其原因,均是由于auto_ptr的“所有权”所致,我们注意到,对于普通的copy ctor,其形式一般为Type(const Type& rhs){...},但对于auto_ptr其copy ctor则不然,
它是auto_ptr(auto_ptr &rhs){...},之所有入参不是const的,那是因为在copy ctor之后,所有权发生了转移(同理还有operator=),即任意时刻,最多只有一个auto_ptr可以
宣称对某一原生指针具有所有权,这对于稍微复杂的场合应用来说显然是不够的(auto_ptr做为参数传递到函数中后原来的auto_ptr就作废了,继续使用原来的auto_ptr会导致错误),
因此tr1引入了shared_ptr/weak_ptr/enable_shared_from_this来解决资源的管理问题。
通过引用计数技术,每当一个weak_ptr/shared_ptr关联到同一资源时,则对应的计数器加一,当weak_ptr/shared_ptr退出作用域时,对应的计数器减一,当计数器值为0时,
则对管理的资源进行释放,我们可以通过注册资源的释放函数(deleter)来处理不同类型的资源释放。
下面根据现有的conceptgcc-boostcon/include/c++/4.3.0/tr1中的smart_ptr实现对smart_ptr进行分析,smart_ptr有shared_ptr/weak_ptr和enable_shared_from_this,
shared_ptr用于对被指向对象的所有权进行共享。被指向对象也保证会被释放(默认是调用delete,否则调用传进来的deleter),但是这将发生在最后一个指向它的shared_ptr被销毁时,
或是显式调用reset 方法时。
weak_ptr用于解决循环引用问题/使用共享资源而不共享所有权以及避免野指针。
enable_shared_from_this用于解决double deletion的问题。
首先介绍class _Sp_counted_base,_Sp_counted_base是weak_ptr/shared_ptr中的底层引用计数器的抽象父类,随着多线程编程的流行,smart_ptr的实现中考虑了多线程的情况,
因此比较复杂,为从根本上简化分析smart_ptr的实现,先去除跟多线程有关的东西,我们简化_Sp_counted_base后得到的代码如下:
class  _Sp_counted_base
{
public:
    _Sp_counted_base(): _M_use_count(
1), _M_weak_count(1{ }
    
virtual ~_Sp_counted_base() // nothrow
    { }

    
// 当_M_use_count的值为0时,调用_M_dispose
    virtual void _M_dispose() = 0// nothrow

    
// 当_M_weak_count的值为0时,调用_M_destroy
    virtual void _M_destroy() // nothrow
    { delete this; }

    
virtual void* _M_get_deleter(const std::type_info&= 0;

    
// 增加_M_use_count的值
    void _M_add_ref_copy()
    
{ __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
        
// 增加_M_use_count的值,同时还会检查其是否发生异常
    void _M_add_ref_lock()
    
{
        
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1== 0)
        
{
            _M_use_count 
= 0;
            __throw_bad_weak_ptr();
        }

    }

        
// 减少_M_use_count的值,当_M_use_count为0时调用_M_dispose,同时让_M_weak_count减一并检查_M_weak_count是否也为0
        
// 因为对于__shared_count,一开始是让_M_use_count跟_M_weak_count都为1,所以当_M_use_count为0时也需要让_M_weak_count减1并检查其值
    void _M_release() // nothrow
    {
        
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1== 1)
        
{
            _M_dispose();
            
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1== 1)
                _M_destroy();
        }

    }

       
        
// 跟_M_use_count一样
    void _M_weak_add_ref() // nothrow
    {
        __gnu_cxx::__atomic_add_dispatch(
&_M_weak_count, 1);
    }


    
void _M_weak_release() // nothrow
    {
        
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1== 1)
        
{
            _M_destroy();
        }

    }


    
long  _M_get_use_count() const // nothrow
    {
        
return _M_use_count;
    }

private:
    _Sp_counted_base(_Sp_counted_base 
const&);
    _Sp_counted_base
& operator=(_Sp_counted_base const&);
    _Atomic_word  _M_use_count;     
// #shared
    _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
}
;
// __weak_count/__shared_count中都有_Sp_counted_base*成员,其实际类型为_Sp_counted_base_impl
// _Sp_counted_base_impl总共有4个成员,用于共享所有权计数的_M_use_count,共享所有树计数和不共享所有权计数的总和_M_weak_count,原生指针_M_ptr,deleter _M_del
template < typename _Ptr, typename _Deleter >
class  _Sp_counted_base_impl :  public  _Sp_counted_base
{
public:
    _Sp_counted_base_impl(_Ptr __p, _Deleter __d) : _M_ptr(__p), _M_del(__d) 
{ }
    
// 当共享计数_M_use_count的值为0时,调用其deleter对资源进行释放
    virtual void _M_dispose() // nothrow
    {
        _M_del(_M_ptr);
    }


    
// 返回deleter
    virtual void* _M_get_deleter(const std::type_info& __ti)
    
{
        
return __ti == typeid(_Deleter) ? &_M_del : 0;
    }


private:
    _Sp_counted_base_impl(
const _Sp_counted_base_impl&);
    _Sp_counted_base_impl
& operator=(const _Sp_counted_base_impl&);
    _Ptr      _M_ptr; 
// 原生指针
    _Deleter  _M_del; // deleter
}
;

// 前向声明__weak_count,__weak_count可以访问__shared_count中的所有成员
class __weak_count;
// __shared_count的构造方法有:使用默认构造函数构造空的;通过原生指针构造;通过auto_ptr构造;通过weak_count构造;通过拷贝函数构造;

class  __shared_count
{
public:
    __shared_count() : _M_pi(
0// nothrow
    { }
       
        
// 构造完成后其_M_use_count和_M_weak_count的值均为1
    template<typename _Ptr, typename _Deleter>
        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(
0)
        
{
            
try
            
{
                _M_pi 
= new _Sp_counted_base_impl<_Ptr, _Deleter>(__p, __d);
            }

            
catch(...)
            
{
                
// 如果构造失败,则调用deleter释放资源
                __d(__p);
                __throw_exception_again;
            }

        }


    
// 通过auto_ptr构造的,其deleter均为delete
    template<typename _Tp> explicit __shared_count(std::auto_ptr<_Tp>& __r) :
        _M_pi(
new _Sp_counted_base_impl<_Tp*, _Sp_deleter<_Tp> >(__r.get(), _Sp_deleter<_Tp>()))
    
{
        __r.release();
    }


    
// 从__weak_count构造__shared_count,如果构造的__shared_count._M_use_count为0,抛出bad_weak_ptr,如果_M_pi为0,也抛出bad_weak_ptr
    
// 后面的enable_shared_from_this就是从weak_count进行构造
    explicit __shared_count(const __weak_count& __r): _M_pi(__r._M_pi)
    
{
        
if (_M_pi != 0)
            _M_pi
->_M_add_ref_lock();
        
else
            __throw_bad_weak_ptr();
    }


    
~__shared_count() // nothrow
    {
        
if (_M_pi != 0)
            _M_pi
->_M_release();
    }


    __shared_count(
const __shared_count& __r) : _M_pi(__r._M_pi)
    
{
        
if (_M_pi != 0)
            _M_pi
->_M_add_ref_copy();
    }


    __shared_count
& operator=(const __shared_count& __r)
    
{
        _Sp_counted_base 
*__tmp = __r._M_pi;
        
if (__tmp != _M_pi)
        
{
            
if (__tmp != 0)
                __tmp
->_M_add_ref_copy();
            
if (_M_pi != 0)
                _M_pi
->_M_release();
            _M_pi 
= __tmp;
        }

        
return *this;
    }


    
void _M_swap(__shared_count& __r)
    
{
        _Sp_counted_base 
*__tmp = __r._M_pi;
        __r._M_pi 
= _M_pi;
        _M_pi 
= __tmp;
    }


    
long _M_get_use_count() const
    
{
        
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0;
    }


    
bool _M_unique() const
    
{
        
return this->_M_get_use_count() == 1;
    }


    friend inline 
bool operator==(const __shared_count& __a, const __shared_count& __b)
    
{
        
return __a._M_pi == __b._M_pi;
    }


    friend inline 
bool operator<(const __shared_count& __a, const __shared_count& __b)
    
{
        
return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi);
    }


    
void* _M_get_deleter(const std::type_info& __ti) const
    
{
        
return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0;
    }


private:
    friend 
class __weak_count;
    _Sp_counted_base 
*_M_pi;
}
;

// __shared_count也是__weak_count的友元类,可以访问__weak_count中的任何成员
// __weak_count的构造只能通过默认构造函数构造空的,通过__shared_count构造,通过拷贝函数构造
class  __weak_count
{
public:
    __weak_count() : _M_pi(
0)
    
{ }

    __weak_count(
const __shared_count& __r) : _M_pi(__r._M_pi)
    
{
        
if (_M_pi != 0)
            _M_pi
->_M_weak_add_ref();
    }


    __weak_count(
const __weak_count& __r) : _M_pi(__r._M_pi)
    
{
        
if (_M_pi != 0)
            _M_pi
->_M_weak_add_ref();
    }


    
~__weak_count()
    
{
        
if (_M_pi != 0)
            _M_pi
->_M_weak_release();
    }


    __weak_count
& operator=(const __shared_count& __r)
    
{
        _Sp_counted_base 
*__tmp = __r._M_pi;
        
if (__tmp != 0)
            __tmp
->_M_weak_add_ref();
        
if (_M_pi != 0)
            _M_pi
->_M_weak_release();
        _M_pi 
= __tmp;
        
return *this;
    }


    __weak_count
& operator=(const __weak_count& __r)
    
{
        _Sp_counted_base 
*__tmp = __r._M_pi;
        
if (__tmp != 0)
            __tmp
->_M_weak_add_ref();
        
if (_M_pi != 0)
            _M_pi
->_M_weak_release();
        _M_pi 
= __tmp;
        
return *this;
    }


    
void _M_swap(__weak_count& __r)
    
{
        _Sp_counted_base
* __tmp = __r._M_pi;
        __r._M_pi 
= _M_pi;
        _M_pi 
= __tmp;
    }


    
long _M_get_use_count() const
    
{
        
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0;
    }


    friend inline 
bool operator==(const __weak_count& __a, const __weak_count& __b)
    
{
        
return __a._M_pi == __b._M_pi;
    }


    friend inline 
bool operator<(const __weak_count& __a, const __weak_count& __b)
    
{
        
return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi);
    }

   
private:
    friend 
class __shared_count;
    _Sp_counted_base 
*_M_pi;
}
;

// 前向声明
template<typename _Tp>
class __shared_ptr;

template<typename _Tp>
class __weak_ptr;

template<typename _Tp>
class __enable_shared_from_this;

template<typename _Tp>
class shared_ptr;

template<typename _Tp>
class weak_ptr;

template<typename _Tp>
class enable_shared_from_this;

// 函数的优先级:如果类有友元函数,则优先调用友元函数;否则调用全局函数
// __shared_ptr时会调用__enable_shared_from_this_helper,如果是派生自__enable_shared_from_this类的,那么有友元函数,调用它
// 否则调用全局函数,全局函数为空,什么都不干
template<typename _Tp1, typename _Tp2>
void __enable_shared_from_this_helper(const __shared_count&, const __enable_shared_from_this<_Tp1>*, const _Tp2*);

template<>
inline void __enable_shared_from_this_helper(const __shared_count&, ...)
{ }

template<typename _Tp1, typename _Tp2>
void __enable_shared_from_this_helper(const __shared_count&, const enable_shared_from_this<_Tp1>*, const _Tp2*);


struct __static_cast_tag { };
struct __const_cast_tag { };
struct __dynamic_cast_tag { };

template < typename _Tp >
class  __shared_ptr
{
public:
    typedef _Tp   element_type;

    
// 构造空的__shared_ptr
    __shared_ptr() : _M_ptr(0), _M_refcount()
    
{ }

    
// 根据原生指针构造__shared_ptr,对原生指针的资源释放使用delete
    
// 如果不是enable_shared_from_this,完成后_M_use_count为1,_M_weak_count为1
    template<typename _Tp1>
        
explicit __shared_ptr(_Tp1* __p) : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
    
{
        
// 如果类是通过派生自__enable_shared_from_this,那么就有__enable_shared_from_this_helper函数的实现,将调用对应的__enable_shared_from_this_helper,
        
// __enable_shared_from_this_helper设置_M_weak_this,使得所有权个数(_M_use_count)加1,而weak_count(_M_weak_count)个数不变
        
// 否则调用__enable_shared_from_this_helper(const __shared_count&, ...),该函数为空
        __enable_shared_from_this_helper(_M_refcount, __p, __p);
    }


    
// 根据原生指针及删除对象构造__shared_ptr,对原生指针的资源的释放使用删除对象来进行
    
// 如果不是enable_shared_from_this,完成后_M_use_count为1,_M_weak_count为1
    template<typename _Tp1, typename _Deleter>
        __shared_ptr(_Tp1
* __p, _Deleter __d) : _M_ptr(__p), _M_refcount(__p, __d)
    
{
        
// 同上
        __enable_shared_from_this_helper(_M_refcount, __p, __p);
    }

    
    
// 从auto_ptr构造__shared_ptr
    template<typename _Tp1>
        
explicit __shared_ptr(std::auto_ptr<_Tp1>& __r) : _M_ptr(__r.get()), _M_refcount()
    
{
        _Tp1
* __tmp = __r.get();
        _M_refcount 
= __shared_count(__r);
        __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    }
  

        
// copy ctor,完成后_M_use_count加1,_M_weak_count不变
    template<typename _Tp1>
        __shared_ptr(
const __shared_ptr<_Tp1>& __r) : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 
    
{ }

    
// 从__weak_ptr构造__shared_ptr,完成后_M_use_count加1,_M_weak_count不变--enable_shared_from_this对应于这种情况
    template<typename _Tp1>
        
explicit __shared_ptr(const __weak_ptr<_Tp1>& __r) : _M_refcount(__r._M_refcount) 
    
{
        _M_ptr 
= __r._M_ptr;
    }


    
// 从不同类型的__shared_ptr构造__shared_ptr,进行static_cast
    template<typename _Tp1>
        __shared_ptr(
const __shared_ptr<_Tp1>& __r, __static_cast_tag) : _M_ptr(static_cast<element_type*>(__r._M_ptr)), _M_refcount(__r._M_refcount)
    
{ }

    
// 从不同类型的__shared_ptr构造__shared_ptr,进行const_cast
    template<typename _Tp1>
        __shared_ptr(
const __shared_ptr<_Tp1>& __r, __const_cast_tag) : _M_ptr(const_cast<element_type*>(__r._M_ptr)), _M_refcount(__r._M_refcount)
    
{ }

    
// 从不同类型的__shared_ptr构造__shared_ptr,进行dynamic_cast
    template<typename _Tp1>
        __shared_ptr(
const __shared_ptr<_Tp1>& __r, __dynamic_cast_tag) : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), _M_refcount(__r._M_refcount)
    
{
        
if (_M_ptr == 0// need to allocate new counter -- the cast failed
            _M_refcount = __shared_count();
    }


    template
<typename _Tp1>
        __shared_ptr
& operator=(const __shared_ptr<_Tp1>& __r) 
    
{
        _M_ptr 
= __r._M_ptr;
        _M_refcount 
= __r._M_refcount; 
        
return *this;
    }


    
// 从auto_ptr赋值得到
    template<typename _Tp1> __shared_ptr& operator=(std::auto_ptr<_Tp1>& __r)
    
{
        __shared_ptr(__r).swap(
*this);
        
return *this;
    }


    
// 重置__shared_ptr为空
    void reset() 
    
{
        __shared_ptr().swap(
*this);
    }


    
// 重置__shared_ptr
    template<typename _Tp1> void reset(_Tp1* __p) 
    
{
        
// Catch self-reset errors.
        _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
        __shared_ptr(__p).swap(
*this);
    }


    
// 重置__shared_ptr
    template<typename _Tp1, typename _Deleter> void reset(_Tp1* __p, _Deleter __d)
    
{
        __shared_ptr(__p, __d).swap(
*this);
    }


    typename add_reference
<_Tp>::type operator*() const 
    
{
        _GLIBCXX_DEBUG_ASSERT(_M_ptr 
!= 0);
        
return *_M_ptr;
    }


    _Tp
* operator->() const 
    
{
        _GLIBCXX_DEBUG_ASSERT(_M_ptr 
!= 0);
        
return _M_ptr;
    }


    _Tp
* get() const 
    
{
        
return _M_ptr;
    }

private:
        
// Implicit conversion to "bool"
    typedef _Tp* __shared_ptr::*__unspecified_bool_type;

public:
    
operator __unspecified_bool_type() const // never throws
    {
        
return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr;
    }

        
        
// 是否只有一个shared_ptr拥有当前资源的所有权
    bool unique() const 
    
{
        
return _M_refcount._M_unique();
    }


    
long use_count() const 
    
{
        
return _M_refcount._M_get_use_count();
    }


    
void swap(__shared_ptr<_Tp>& __other) 
    
{
        std::swap(_M_ptr, __other._M_ptr);
        _M_refcount._M_swap(__other._M_refcount);
    }


private:
    
void* _M_get_deleter(const std::type_info& __ti) const
    
{
        
return _M_refcount._M_get_deleter(__ti);
    }


    template
<typename _Tp1> bool _M_less(const __shared_ptr<_Tp1>& __rhs) const
    
{
        
return _M_refcount < __rhs._M_refcount;
    }


    template
<typename _Tp1> friend class __shared_ptr;
    template
<typename _Tp1> friend class __weak_ptr;

    template
<typename _Del, typename _Tp1> friend _Del* get_deleter(const __shared_ptr<_Tp1>&);

    
// Friends injected into enclosing namespace and found by ADL:
    template<typename _Tp1> friend inline bool operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1>& __b)
    
{
        
return __a.get() == __b.get();
    }


    template
<typename _Tp1> friend inline bool operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1>& __b)
    
{
        
return __a.get() != __b.get();
    }


    template
<typename _Tp1> friend inline bool operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1>& __b)
    
{
        
return __a._M_less(__b);
    }


    _Tp 
*_M_ptr;                                 // 资源指针
    __shared_count  _M_refcount;    // 与该资源相关的计数器
}
;

template
< typename _Tp >
inline 
void  swap(__shared_ptr < _Tp >&  __a, __shared_ptr < _Tp >&  __b)
{
    __a.swap(__b);
}


template
< typename _Tp, typename _Tp1 >
__shared_ptr
< _Tp >  static_pointer_cast( const  __shared_ptr < _Tp1 >&  __r)
{
    
return __shared_ptr<_Tp>(__r, __static_cast_tag());
}


template
< typename _Tp, typename _Tp1 >
__shared_ptr
< _Tp >  const_pointer_cast( const  __shared_ptr < _Tp1 >&  __r)
{
    
return __shared_ptr<_Tp>(__r, __const_cast_tag());
}


template
< typename _Tp, typename _Tp1 >
__shared_ptr
< _Tp >  dynamic_pointer_cast( const  __shared_ptr < _Tp1 >&  __r)
{
    
return __shared_ptr<_Tp>(__r, __dynamic_cast_tag());
}


template
< typename _Ch, typename _Tr, typename _Tp >
std::basic_ostream
< _Ch, _Tr >&   operator << (std::basic_ostream < _Ch, _Tr >&  __os,  const  __shared_ptr < _Tp >&  __p)
{
    __os 
<< __p.get();
    
return __os;
}


template
< typename _Del, typename _Tp >
inline _Del
*  get_deleter( const  __shared_ptr < _Tp >&  __p)
{
    
return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
}

// __weak_ptr只能通过默认构造函数构造/__weak_ptr进行拷贝构造/__shared_ptr进行构造
template < typename _Tp >
class  __weak_ptr
{
public:
    typedef _Tp element_type;

      
// default ctor,构造空的__weak_ptr
    __weak_ptr() : _M_ptr(0), _M_refcount()
    
{ }

    
// copy ctor
    template<typename _Tp1>
        __weak_ptr(
const __weak_ptr<_Tp1>& __r) : _M_refcount(__r._M_refcount)
    
{
        _M_ptr 
= __r.lock().get();
    }


    
// 从__shared_ptr构造__weak_ptr,完成后_M_use_count不变,_M_weak_count加1
    template<typename _Tp1>
        __weak_ptr(
const __shared_ptr<_Tp1>& __r) : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
    
{  }

    template
<typename _Tp1>
        __weak_ptr
& operator=(const __weak_ptr<_Tp1>& __r)
    
{
         _M_ptr 
= __r.lock().get();
        _M_refcount 
= __r._M_refcount;
        
return *this;
    }


    template
<typename _Tp1>
    __weak_ptr
& operator=(const __shared_ptr<_Tp1>& __r)
    
{
        _M_ptr 
= __r._M_ptr;
        _M_refcount 
= __r._M_refcount;
        
return *this;
    }


    
// 如果__shared_ptr的引用计数为0,则返回空的__shared_ptr,否则返回由__weak_ptr构造的__shared_ptr
        __shared_ptr<_Tp>
        
lock() const
        
{
            
return expired() ? __shared_ptr<element_type>() : __shared_ptr<element_type>(*this);
        }


    
long use_count() const
    
{
        
return _M_refcount._M_get_use_count();
    }


    
bool expired() const
    
{
        
return _M_refcount._M_get_use_count() == 0;
    }


    
void reset()
    
{
        __weak_ptr().swap(
*this);
    }


    
void swap(__weak_ptr& __s)
    
{
        std::swap(_M_ptr, __s._M_ptr);
            _M_refcount._M_swap(__s._M_refcount);
    }

private:
    
// 被__enable_shared_from_this所调用
    
// 完成后_M_use_count不变,_M_weak_count加1
    void _M_assign(_Tp* __ptr, const __shared_count& __refcount)
    
{
        _M_ptr 
= __ptr;
        _M_refcount 
= __refcount;
    }


    template
<typename _Tp1>
    
bool _M_less(const __weak_ptr<_Tp1>& __rhs) const
    
{
        
return _M_refcount < __rhs._M_refcount;
    }


    template
<typename _Tp1> friend class __shared_ptr;
    friend 
class __enable_shared_from_this<_Tp>;
    friend 
class enable_shared_from_this<_Tp>;

    
// Friend injected into namespace and found by ADL.
    template<typename _Tp1>    friend inline bool operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1>& __rhs)
    
{
        
return __lhs._M_less(__rhs);
    }


    _Tp
*            _M_ptr;         // 资源指针
    __weak_count  _M_refcount;    // 与资源指针关联的计数器
}
;

template
< typename _Tp >
inline 
void  swap(__weak_ptr < _Tp >&  __a, __weak_ptr < _Tp >&  __b)
{
    __a.swap(__b);
}


template < typename _Tp >
class  __enable_shared_from_this
{
protected:
    __enable_shared_from_this() 
{ }
    __enable_shared_from_this(
const __enable_shared_from_this&{ }

    __enable_shared_from_this
& operator=(const __enable_shared_from_this&)
    
{
        
return *this;
    }


    
~__enable_shared_from_this() { }

public:
    __shared_ptr
<_Tp> shared_from_this()
    
{
        
return __shared_ptr<_Tp>(this->_M_weak_this);
    }


    __shared_ptr
<const _Tp> shared_from_this() const
    
{
        
return __shared_ptr<const _Tp>(this->_M_weak_this);
    }


private:
    template
<typename _Tp1> void _M_weak_assign(_Tp1* __p, const __shared_count& __n) const
    
{
        _M_weak_this._M_assign(__p, __n);
    }


    template
<typename _Tp1>
        friend 
void __enable_shared_from_this_helper(const __shared_count& __pn, const __enable_shared_from_this* __pe, const _Tp1* __px)
        
{
            
if (__pe != 0)
                __pe
->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
        }

    mutable __weak_ptr
<_Tp>  _M_weak_this;
}
;

template < typename _Tp >
class  shared_ptr :  public  __shared_ptr < _Tp >
{
public:
    shared_ptr() : __shared_ptr
<_Tp>() { }

    template
<typename _Tp1>
        
explicit shared_ptr(_Tp1* __p) : __shared_ptr<_Tp>(__p) { }

    template
<typename _Tp1, typename _Deleter>
        shared_ptr(_Tp1
* __p, _Deleter __d) : __shared_ptr<_Tp>(__p, __d) { }

    template
<typename _Tp1>
        shared_ptr(
const shared_ptr<_Tp1>& __r) : __shared_ptr<_Tp>(__r) { }

    template
<typename _Tp1>
        
explicit shared_ptr(const weak_ptr<_Tp1>& __r) : __shared_ptr<_Tp>(__r) { }

    template
<typename _Tp1>
        
explicit shared_ptr(std::auto_ptr<_Tp1>& __r) : __shared_ptr<_Tp>(__r) { }

    template
<typename _Tp1>
        shared_ptr(
const shared_ptr<_Tp1>& __r, __static_cast_tag) : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }

    template
<typename _Tp1>
        shared_ptr(
const shared_ptr<_Tp1>& __r, __const_cast_tag) : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }

    template
<typename _Tp1>
        shared_ptr(
const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
    template
<typename _Tp1>
        shared_ptr
& operator=(const shared_ptr<_Tp1>& __r) // never throws
    {
        
this->__shared_ptr<_Tp>::operator=(__r);
        
return *this;
    }


    template
<typename _Tp1>
        shared_ptr
& operator=(std::auto_ptr<_Tp1>& __r)
    
{
        
this->__shared_ptr<_Tp>::operator=(__r);
        
return *this;
    }

}
;

template
< typename _Tp, typename _Tp1 >
shared_ptr
< _Tp >  static_pointer_cast( const  shared_ptr < _Tp1 >&  __r)
{
    
return shared_ptr<_Tp>(__r, __static_cast_tag());
}


template
< typename _Tp, typename _Tp1 >
shared_ptr
< _Tp >  const_pointer_cast( const  shared_ptr < _Tp1 >&  __r)
{
    
return shared_ptr<_Tp>(__r, __const_cast_tag());
}


template
< typename _Tp, typename _Tp1 >
shared_ptr
< _Tp >  dynamic_pointer_cast( const  shared_ptr < _Tp1 >&  __r)
{
    
return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
}


template
< typename _Tp >
class  weak_ptr :  public  __weak_ptr < _Tp >
{
public:
    weak_ptr() : __weak_ptr
<_Tp>() { }

    template
<typename _Tp1>
        weak_ptr(
const weak_ptr<_Tp1>& __r) : __weak_ptr<_Tp>(__r) { }

    template
<typename _Tp1>
        weak_ptr(
const shared_ptr<_Tp1>& __r) : __weak_ptr<_Tp>(__r) { }

    template
<typename _Tp1>
        weak_ptr
& operator=(const weak_ptr<_Tp1>& __r) // never throws
    {
        
this->__weak_ptr<_Tp>::operator=(__r);
        
return *this;
    }


    template
<typename _Tp1>
        weak_ptr
& operator=(const shared_ptr<_Tp1>& __r) // never throws
    {
        
this->__weak_ptr<_Tp>::operator=(__r);
        
return *this;
    }


    shared_ptr
<_Tp> lock() const // never throws
    {
        
return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this);
    }

}
;


template
< typename _Tp >
class  enable_shared_from_this
{
protected:
    enable_shared_from_this() 
{ }
    enable_shared_from_this(
const enable_shared_from_this&{ }
    enable_shared_from_this
& operator=(const enable_shared_from_this&)
    
{
        
return *this;
    }


    
~enable_shared_from_this() { }

public:
        
// 使其_M_use_count加1
    shared_ptr<_Tp> shared_from_this()
    
{
        
return shared_ptr<_Tp>(this->_M_weak_this);
    }

    
        
// 使其_M_use_count加1
    shared_ptr<const _Tp> shared_from_this() const
    
{
        
return shared_ptr<const _Tp>(this->_M_weak_this);
    }


private:
    template
<typename _Tp1>
        
void _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
        
{
            _M_weak_this._M_assign(__p, __n);
        }

        
        
// 使其_M_weak_count加1
    template<typename _Tp1>
        friend 
void __enable_shared_from_this_helper(const __shared_count<>& __pn, const enable_shared_from_this* __pe, const _Tp1* __px)
        
{
            
if (__pe != 0)
                __pe
->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
        }


    mutable weak_ptr
<_Tp>  _M_weak_this;
}
;

// enable_shared_from_this存在的理由是对于以下代码,将出现double deletion,这是致命的
// 引自Stephan T. Lavavej的shared_ptr.pptx 
    struct  Ansible  {
        shared_ptr
<Ansible> get_shared() {
            shared_ptr
<Ansible> ret(this);
            
return ret;
        }

    }
;

    
int  main()  {
        shared_ptr
<Ansible> a(new Ansible);
        Ansible
& r = *a;
        shared_ptr
<Ansible> b = r.get_shared();
    }
// 而通过enable_shared_from_this,可以避免这个问题
 
   struct  Ansible
        : 
public  enable_shared_from_this < Ansible >   { } ;

    
int  main()  {
        shared_ptr
<Ansible> a(new Ansible);
        Ansible
& r = *a;
        shared_ptr
<Ansible> b = r.shared_from_this();
    }
 
跟前面代码分析的一样,通过enable_shared_from_this,构造b时增加_M_use_count和_M_weak_count的值,因此不会出现double delete的情况

下面给出smart_ptr的示例代码:
1 . shared_ptr
A.
{
    FILE
*fptr = fopen("some_path""mode");
    shared_ptr
<FILE> Fptr(fptr, fclose);
    ...
// 使用Fptr,退出作用域时释放fptr
}


B.
{
    
struct Foo{
        shared_ptr
<FILE> m_fptr;
        Foo()
{}
        Foo(
const char *filename, const char *mode):m_fptr(fopen(filename, mode), fclose){}
    }
;
    Foo f1(
"some_path""mode");
    
// use f1
    Foo f2(f1);
    
// use f2
    Foo f3;
    f3 
= f1;
    
// use f3
    
// f1,f2,f3都拥有同一文件的所有权,只有退出作用域时才会释放资源
}

C.把share_ptr
< Type > 插入到容器中

2 . weak_ptr
解决循环引用(circular reference)的问题,参考《
Smart Pointers to boost your code》
《A beginner's introduction to the smart pointers provided by the boost library》 By peterchen

{
struct CSample{};
struct CDad;
struct CChild;
typedef shared_ptr
<CDad>   CDadPtr;
typedef shared_ptr
<CChild> CChildPtr;
struct CDad : public CSample
{
    CChildPtr myBoy;
}
;
struct CChild : public CSample
{
    CDadPtr myDad;
}
;

    CDadPtr dad(
new CDad);
    CChildPtr child(
new CChild);
    dad
->myBoy = child;
    child
->myDad = dad;
    child.reset();
    
// dad还引用到CDad对象,而CDad对象引用到CChild对象
    dad.reset();
    
// 此时dad和child的引用计数器的值均为1,出现了内存泄露
}

通过weak_ptr的解决办法如下:
{
struct CSample{};
struct CDad;
struct CChild;
typedef shared_ptr
<CDad>   CDadPtr;
typedef shared_ptr
<CChild> CChildPtr;
struct CDad : public CSample
{
    weak_ptr
<CChild> myBoy;
}
;
struct CChild : public CSample
{
    weak_ptr
<CDad> myDad;
}
;

    CDadPtr dad(
new CDad);
    CChildPtr child(
new CChild);
    dad
->myBoy = child;
    child
->myDad = dad;
    child.reset();
    dad.reset();
}

3 .enable_shared_from_this的例子见Stephan T. Lavavej的shared_ptr.pptx,即上面的代码

通过上面的源码分析,我实现一个迷你版本的my_shared_ptr,不考虑多线程情况,源码如下:

template < typename ClassType, typename Deleter >
class  my_shared_ptr {
private:
    ClassType 
*m_ptr;
    Deleter m_deleter; 
// Deleter必须有default ctor和copy ctor,对于非类类型,具有bitwise copy语义
    int *m_refCount;
public:
    my_shared_ptr(): m_ptr(
0), m_refCount(0){}

    my_shared_ptr(ClassType 
*ptr, Deleter deleter = Deleter()): m_ptr(ptr), m_deleter(deleter)
    
{
        m_refCount 
= new int(1);
    }

    
~my_shared_ptr()
    
{
        
*m_refCount -= 1;
        
if (*m_refCount == 0{
            m_deleter(m_ptr);
            delete m_refCount;
        }

    }

    ClassType
* operator->()
    
{
        
return m_ptr;
    }


    ClassType
& operator*()
    
{
        
return *m_ptr;
    }


    my_shared_ptr(
const my_shared_ptr &rhs)
    
{
        m_ptr 
= rhs.m_ptr;
        m_deleter 
= rhs.m_deleter;
        m_refCount 
= rhs.m_refCount;
        
if( m_refCount )
        
{
            
*m_refCount += 1;
        }

    }

    template
<typename OtherClassType, typename OtherDeleter>
    my_shared_ptr
& operator=(const my_shared_ptr<OtherClassType, OtherDeleter> &rhs)
    
{
        
if (this != &rhs) {
            
*m_refCount -= 1;
            
if (*m_refCount == 0{
                m_deleter(m_ptr);
                delete m_refCount;
            }

            m_ptr 
= rhs.m_ptr;
            m_deleter 
= rhs.m_deleter;
            m_refCount 
= rhs.m_refCount;
            
if( m_refCount )
            
{
                
*m_refCount += 1;
            }

            
return *this;
        }

        
return *this;
    }


    
operator ClassType*()
    
{
        
return m_ptr;
    }

}
;

顺带说一下,在网上翻资料的时候看到智能指针使用了特殊的observer模式,确实如此。

你可能感兴趣的:(tr1中的智能指针详解及使用示例(Rev))