boost::enable_shared_from_this的部分实现研究

 

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机制的实现时,发现以下代码:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> 1  template <   class  X,  class  Y,  class  T  >
2  inline  void  sp_enable_shared_from_this( boost::shared_ptr < X >   const   *  ppx, Y  const   *  py, boost::enable_shared_from_this <  T  >   const   *  pe )
3  {
4       if ( pe  !=   0  )
5      {
6          pe -> _internal_accept_owner( ppx, const_cast <  Y *   > ( py ) );
7      }
8  }
这个函数就是设置被管理类中的weak_ptr的。那么这个函数什么时候被调用呢?是在shared_ptr的构造函数中:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> 1  template < class  Y >
2  explicit  shared_ptr( Y  *  p ): px( p ), pn( p )  //  Y must be complete
3  {
4      boost::detail::sp_enable_shared_from_this(  this , p, p );
5  }

这里比较奇怪的地方就是sp_enable_shared_from_this这个函数是始终被调用的,但是如果被管理类没有继承自 enable_shared_from_this,那这个调用肯定是通不过的,因为指向普通类型Y的指针p不能转型为指向 enable_shared_from_this类的指针。继续翻代码,发现sp_enable_shared_from_this函数的一个重载:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> 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那么不会有任何函数调用发生。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值