enable_from_this 的使用与实现原理说明:
 
shared_from_this()是enable_shared_from_this的成员函数,返回shared_ptr;
注意的是,这个函数仅在shared_ptr的构造函数被调用之后才能使用。
原因是enable_shared_from_this::weak_ptr并不在构造函数中设置,而是在shared_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. 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 ;
  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 ;
  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 的构造方式,
所以boost::enable_shared_from_this中的weak_ptr所指的函数对象也就没有被赋值,
在调用d.func()中使用shared_from_this()函数时
 
----注:shared_from_this的函数实现 ------
    shared_ptr shared_from_this()
    {
        shared_ptr 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 ;
  27. }

执行结果:

D::D()
D::func()

(转)enable_from_this方法的使用与陷阱的更多相关文章

  1. 使用Runtime.getRuntime().exec()方法的几个陷阱 (转)

    Process 子类的一个实例,该实例可用来控制进程并获得相关信息.Process 类提供了执行从进程输入.执行输出到进程.等待进程完成.检查进程的退出状态以及销毁(杀掉)进程的方法. 创建进程的方法 ...

  2. [转]使用Runtime.getRuntime().exec()方法的几个陷阱

    Process 子类的一个实例,该实例可用来控制进程并获得相关信息.Process 类提供了执行从进程输入.执行输出到进程.等待进程完成.检查进程的退出状态以及销毁(杀掉)进程的方法. 创建进程的方法 ...

  3. 使用Runtime.getRuntime().exec()方法的几个陷阱

    Process 子类的一个实例,该实例可用来控制进程并获得相关信息.Process 类提供了执行从进程输入.执行输出到进程.等待进程完成.检查进程的退出状态以及销毁(杀掉)进程的方法. 创建进程的方法 ...

  4. 2016-11-02: boost::enable_shared_from_this

    使用场景 当类对象被shared_ptr管理时,需要在类自己定义的函数中把当前对象作为参数传递给其他函数时,必须传递一个shared_ptr,否则就不能保持shared_ptr管理这个类对象的语义.因 ...

  5. CO-类的本质、description方法

    类的本质 1. 类也是个对象 其实类也是一个对象,是Class类型的对象,简称“类对象” Class类型的定义 typedef struct objc_class  *Class; 类名就代表着类对象 ...

  6. OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法

    一. 分类-Category 1. 基本用途:Category  分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...

  7. 执行Runtime.exec()需要注意的陷阱

    作为Java语言的一部分.java.lang包被隐藏的导入到每一个Java程序.这个包的表面陷阱,经常影响到大多数程序员.这个月,我将讨论运行时exec()方法时的潜伏陷阱. 陷阱4:当运行exec( ...

  8. Java-技术专区-技术栈分析辨证方法

    1.好多公司动不动就JVM.高并发.分布式.微服务等等,我没有实际经验. 2.从事Java开发三年了,目前的职位是高级Java工程师,感觉技术和工资都到了瓶颈,对以后的发展方向有些迷茫. 3.加班时间 ...

  9. JavaScript性能优化

    如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...

随机推荐

  1. SecureCRT 用法总结

    SecureCRT 用法总结   1.下载与破解方法: Mac:https://www.jianshu.com/p/9427f12b1fdb Window:https://drive.google.c ...

  2. 火狐浏览器油猴子GreaseMonkey使用教程

    火狐浏览器油猴子GreaseMonkey使用教程 首先下载火狐浏览器 安装成功后用火狐浏览器打开链接,界面如下 然后搜索GreaseMonkey. 搜索结果,图标是个小猴子,然后添加到火狐浏览器,成功 ...

  3. Python字符串符号:双引号/单引号用法注解。

    众所周知python中单引号和双引号常常被我们所使用,例如print.input等等. 但是对于打印输出所引导的字符串大多都是用双引号的形式来做,"Hello,python!",而 ...

  4. Unity中使用C#实现UDP广播

    没有系统的学习过网络,想做联机游戏还真是费劲,想做在局域网内实现自动搜索服务器的功能,然后就想到了使用UDP进行广播,把服务器的信息广播给每一个玩家. Socket udpSocket = new S ...

  5. junit测试类防止事务回滚-工作心得

    本随笔文章,由个人博客(鸟不拉屎)转移至博客园 发布时间: 2018 年 12 月 06 日 原地址:https://niaobulashi.com/archives/junit-test-rollb ...

  6. C++ chrono 库中的 steady_clock 和 system_clock

    C++11 中提供了一个计时的标准库 <chrono>; 里面有三种时钟 clock: steady_clock, system_clock 和 high_resolution_clock ...

  7. 2018爆零记第二弹之day0

    话说初赛水了个70分,ε=(´ο`*)))唉,还是太菜了. 今天两点左右到了电子科大对面宾馆,收拾安顿好后又去电子科大踩点. 进门又走过了不长不短的水杉道,来到了不大不小的西湖(为什么是这个名字... ...

  8. Hyperledger Fabric chaincode 开发(疑难解答)

    Q&A Q1: 使用fabric release 1.2 进行golang chaincode开发时报错: ..\..\hyperledger\fabric\vendor\github.com ...

  9. python数据分析系列(1)

    目录 python基础 python语言基础 Ipython的一些特性 Python语法基础 Python控制流 lambda表达式 Python的数据结构 元组 列表 字典 集合 列表.集合.字典推 ...

  10. Django_用户权限管理rbac

    组成部分 1.初始化权限:login视图initial_permission,把权限信息放入session.initial_permission函数生成权限列表.菜单列表 2.中间件验证权限:在第一次 ...