shared_from_this bad_weak_ptr的原因

前几天解了一个bug,表象是调用shared_from_this的时候就跑出bad_weak_ptr异常,类A明明是继承自boost::enable_shared_from_this<A>的,一时搞不明白为什么,后来搜了下出现“bad_weak_ptr异常”可能的原因才找到问题所在:创建类A的对象的时候没有用智能指针包裹,而是直接new的裸指针


【引申】


enable_from_this 的使用与实现原理说明

shared_from_this()是enable_shared_from_this<T>的成员函数,返回shared_ptr<T>;
注意的是,这个函数仅在shared_ptr<T>的构造函数被调用之后才能使用。
原因是enable_shared_from_this::weak_ptr并不在构造函数中设置,而是在shared_ptr<T>的构造函数中设置。


错误的使用代码一

  1. #include <boost/shared_ptr.hpp>  
  2. #include <boost/enable_shared_from_this.hpp>  
  3.   
  4. #include <iostream>  
  5. using namespace std;  
  6.   
  7. class D: public boost::enable_shared_from_this<D>  
  8. {  
  9. public:  
  10.     D()  
  11.     {  
  12.         cout<<"D::D()"<<endl;  
  13.         boost::shared_ptr<D> p = shared_from_this();  
  14.     }      
  15. };  
  16.   
  17. int main()  
  18. {  
  19.     boost::shared_ptr<D> a(new D);  
  20.     return 0;      
  21. }  


程序编译通过,执行结果如下:
D::D()
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
what(): tr1::bad_weak_ptr
Aborted

说明在D的构造函数中调用shared_from_this(), 此时D的实例本身尚未构造成功,weak_ptr也就尚未设置,所以程序抛出tr1::bad_weak_ptr异常。

错误的使用代码二:

  1. #include <boost/shared_ptr.hpp>  
  2. #include <boost/enable_shared_from_this.hpp>  
  3.   
  4. #include <iostream>  
  5. using namespace std;  
  6.   
  7. class D: public boost::enable_shared_from_this<D>  
  8. {  
  9. public:  
  10.     D()  
  11.     {  
  12.         cout<<"D::D()"<<endl;  
  13.     }  
  14.       
  15.     void func()  
  16.     {  
  17.         cout<<"D::func()"<<endl;  
  18.         boost::shared_ptr<D> p = shared_from_this();  
  19.     }      
  20. };  
  21.   
  22. int main()  
  23. {  
  24.     D d;  
  25.     d.func();  
  26.     return 0;      
  27. }  


程序编译通过,执行结果如下:
D::D()
D::func()
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
what(): tr1::bad_weak_ptr
Aborted

失败原因分析:

在主函数main中,D的实例是在栈上构造,没有使用boost::shared_ptr<D> 的构造方式,
所以boost::enable_shared_from_this<D>中的weak_ptr所指的函数对象也就没有被赋值,
在调用d.func()中使用shared_from_this()函数时

----注:shared_from_this的函数实现 ------
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}

----注:shared_from_this的函数实现 ------

调用BOOST_ASSERT( p.get() == this ); 失败,抛出以上异常。


最后,我们给出share_from_this()的正确使用例子:
  1. #include <boost/shared_ptr.hpp>  
  2. #include <boost/enable_shared_from_this.hpp>  
  3.   
  4. #include <iostream>  
  5. using namespace std;  
  6.   
  7. class D: public boost::enable_shared_from_this<D>  
  8. {  
  9. public:  
  10.     D()  
  11.     {  
  12.         cout<<"D::D()"<<endl;  
  13.     }  
  14.       
  15.     void func()  
  16.     {  
  17.         cout<<"D::func()"<<endl;  
  18.         boost::shared_ptr<D> p = shared_from_this();  
  19.     }      
  20. };  
  21.   
  22. int main()  
  23. {  
  24.     boost::shared_ptr<D> p(new D);  
  25.     p->func();  
  26.     return 0;      
  27. }      

执行结果:
D::D()
D::func()
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值