enable_from_this 的使用与实现原理说明:
 
shared_from_this()是enable_shared_from_this的成员函数,返回shared_ptr;
注意的是,这个函数仅在shared_ptr的构造函数被调用之后才能使用。
原因是enable_shared_from_this::weak_ptr并不在构造函数中设置,而是在shared_ptr的构造函数中设置。
 
错误的使用代码一:

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <iostream>
using namespace std; class D: public boost::enable_shared_from_this<D>
{
public:
D()
{
cout<<"D::D()"<<endl;
boost::shared_ptr<D> p = shared_from_this();
}
}; int main()
{
boost::shared_ptr<D> a(new D);
return ;
}

程序编译通过,执行结果如下:

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异常。
 
 
错误的使用代码二:
 
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <iostream>
using namespace std; class D: public boost::enable_shared_from_this<D>
{
public:
D()
{
cout<<"D::D()"<<endl;
} void func()
{
cout<<"D::func()"<<endl;
boost::shared_ptr<D> p = shared_from_this();
}
}; int main()
{
D d;
d.func();
return ;
}

程序编译通过,执行结果如下:

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()的正确使用例子:
 

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <iostream>
using namespace std; class D: public boost::enable_shared_from_this<D>
{
public:
D()
{
cout<<"D::D()"<<endl;
} void func()
{
cout<<"D::func()"<<endl;
boost::shared_ptr<D> p = shared_from_this();
}
}; int main()
{
boost::shared_ptr<D> p(new D);
p->func();
return ;
}

执行结果:

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. java多线程相关代码

    1.创建线程的三种方式 使用Thread package com.wpbxx.test; //1.自定义一个类,继承java.lang包下的Thread类 class MyThread extends ...

  3. Spring学习(4)IOC容器配置bean:定义与实例化

    一.  IOC容器配置 1. 一些概念 (1)IOC容器: 定义:具有管理对象和管理对象之间的依赖关系的容器. 作用:应用程序无需自己创建对象,对象由IOC容器创建并组装.BeanFactory是IO ...

  4. cal命令详解

    基础命令学习目录首页 原文链接:https://www.yiibai.com/linux/cal.html cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳 ...

  5. [linux] tmux终端复用神器 [转载]

    转载https://www.cnblogs.com/kevingrace/p/6496899.html Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授 ...

  6. Scrum立会报告+燃尽图(十二月六日总第三十七次):程序功能逻辑优化

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...

  7. 作业要求20181204-7 Final阶段第1周/共1周 Scrum立会报告+燃尽图 02

    作业要求参见https://edu.cnblogs.com/campus/nenu/2018fall/homework/2481 版本控制地址https://git.coding.net/lglr20 ...

  8. 《Java学习笔记JDK8》学习总结

    chapter 6   继承与多态 6.1何谓继承 1.继承的定义:继承就是避免多个类间重复定义共同行为. 2.总结:教材中通过设计一款RPG游戏的部分代码向我们展示了“重复”程序代码的弊端,为了改进 ...

  9. wdatepicker控件de使用小方法汇总

    在总结wdatepicker控件的使用前,先插播一条吧,下午刚心血来潮百度的一条 问?C#中Int16.Int32.Int64.之间的区别,:::嘿嘿其实百度知道就有,但还是写上吧! Int16 表示 ...

  10. NetFPGA-SUME下reference_nic测试

    Reference_nic Reference_nic是NetFPGA-SUME中提供的一个参考Demo,本文主要介绍如何构建并在SUME上运行reference_nic. GIT源 git clon ...