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那么不会有任何函数调用发生。
文章不错,呵呵
C++研究得很深啊,学习!