日志标签 ‘C++’

boost::enable_shared_from_this的部分实现研究

2010年2月2日

shared_ptr是boost库实现的几个智能指针中最重要的,其使用引用计数机制来管理资源。

如果一个类由shared_ptr管理,而在这个类的某个方法又需要传出一个指向自身的指针,那么这个指针也必须被shared_ptr所管理。boost库的实现方法为让被管理类继承boost::enable_shared_from_this类,此后通过shared_from_this函数获得指向自身的shared_ptr。

enable_shared_from_this实质上是把一个weak_ptr作为被管理类的成员,其观察资源使用情况,在调用shared_from_this函数时就是通过这个weak_ptr生成了一个shared_ptr。研读enable_shared_from_this机制的实现时,发现以下代码:

105
106
107
108
109
110
111
112
template< class X, class Y, class T >
inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
{
    if( pe != 0 )
    {
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
    }
}

这个函数就是设置被管理类中的weak_ptr的。那么这个函数什么时候被调用呢?是在shared_ptr的构造函数中:

186
187
188
189
190
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
    boost::detail::sp_enable_shared_from_this( this, p, p );
}

这里比较奇怪的地方就是sp_enable_shared_from_this这个函数是始终被调用的,但是如果被管理类没有继承自enable_shared_from_this,那这个调用肯定是通不过的,因为指向普通类型Y的指针p不能转型为指向enable_shared_from_this类的指针。继续翻代码,发现sp_enable_shared_from_this函数的一个重载:
inline void sp_enable_shared_from_this( … ){}
原来这个地方充分利用了函数重载发现机制,如果被管理类继承自enable_shared_from_this,那么第一个sp_enable_shared_from_this就是最合适的,shared_ptr的构造函数中会调用这个版本。否则,就会调用第二个sp_enable_shared_from_this函数也就是最通用化的版本,因为…就是不定参数,它可以接受任何传入的类型。而这个参数又是一个空函数,什么事都不会发生。

这种实现方式也避免了效率的降低,因为2个sp_enable_shared_from_this都是内联inline的,这就保证了如果不需要设置weak_ptr那么不会有任何函数调用发生。

无觅相关文章插件,快速提升流量