2019独角兽企业重金招聘Python工程师标准>>>

Tips不要在 enble_shared_from_this 派生类中的构造函数中使用 weak_from_this() 或 shared_from_this(),将该过程放到 initialize() 中去处理。

继承于 boost::enable_shared_from_this 的类,在其构造的过程中,不能使用 shared_from_this() 与 weak_from_this() 函数。因为此时,enable_shared_from_this 基类的成员变量都还没有初始化好。

如下示例:

#include <iostream>
#include <boost/smart_ptr.hpp>#define EnableSharedFromThis boost::enable_shared_from_this
#define SharedPtr boost::shared_ptr
#define WeakPtr boost::weak_ptr
#define MakeShared boost::make_sharedclass B;class A : public EnableSharedFromThis<A> {public:A() {sp_b_ = MakeShared<B>(weak_from_this());  //! 在 A 的构造函数中使用了 weak_from_this()}SharedPtr<B> getB() const {return sp_b_;}void print() const {std::cout << "A::print()" << std::endl;}private:SharedPtr<B> sp_b_;
};class B {public:B(WeakPtr<A> sp) : sp_(sp){}void letAPrint() const {SharedPtr<A> sp_a(sp_);sp_a->print();}private:WeakPtr<A> sp_;
};int main() {SharedPtr<A> a = MakeShared<A>();SharedPtr<B> b = a->getB();b->letAPrint();return 0;
}

上述代码的功能是:

A要构造函数中构造一个B,但是在构造的时候要给B对像传入A的引用指针。

编译没有问题,但执行出错:

问题出在代码中红色标记处。此时传给B()构造函数的WeakPtr<A>是无效的。

使用 gdb 调试时发现,在执行到L14时,A的基类成员 boost::enable_shared_from_this 的内容依旧是空的。如下:

说明一下:shared_ptr 中存有一个weak_ptr,而weak_ptr对象有两个指针:px 指向对象实体,而 pn.pi_ 则指向的是指针的计数对象。

如上两个指针都是空的,足于说明这 enable_shared_from_this 没有实际的内容。

其实 weak_from_this() 函数什么都没干,只是将这个没有实际内容的 weak_ptr 给了出去。可想而知,在测试代码中 B 拿到的是一个无效的 weak_ptr,所以后面的 B::letAPrint() 是会出错的。

那么,在什么时候 enable_shared_from_this 中的 weak_this_ 被赋于有效的值呢?

在 make_shared() 的最后一步才赋值的。

如果我不使用 make_shared() 又将如何呢?它最终会有 boost::detail::sp_enable_shared_from_this() 这一步吗?

可见,也有这个过程。

如果 A 不使用智能指针直接new,或将A作为栈中的数据。可以想到它出错,因为没有 boost::detail::sp_enable_shared_from_this() 过程。那么内部的 shared_from_this() 与 weak_from_this() 就是无效的数据。

了解了其问题原因,那么就可以很好地找到其解决办法了。

不要在enble_shared_from_this 派生类中的构造函数中使用 weak_from_this() 或 shared_from_this(),将该过程放到 initialize() 中去处理。

对示例做如下修改:

执行结果达到预期效果。

转载于:https://my.oschina.net/hevakelcj/blog/2059230

智能指针 enable_shared_from_this 陷阱相关推荐

  1. 浅析 C++智能指针和 enable_shared_from_this 机制

    作者 | 小牛  责编 | 阿哲 头图 | CSDN 下载自视觉中国 来源 | 后端技术小牛说(ID:gh_acfd77ed3228) 今天跟聊一下 BAT 面试 C++ 开发工程师必问的一个考点:智 ...

  2. c++ 智能指针_详解 C++ 11 中的智能指针

    C/C++ 语言最为人所诟病的特性之一就是存在内存泄露问题,因此后来的大多数语言都提供了内置内存分配与释放功能,有的甚至干脆对语言的使用者屏蔽了内存指针这一概念.这里不置贬褒,手动分配内存与手动释放内 ...

  3. C++智能指针 intrusive_ptr

    intrusive_ptr: intrusive_ptr是一个侵入式的引用计数型指针,它可以用于以下两种情形: [1]对内存占用的要求非常严格,要求必须与原始指针一样: [2]现存代码已经有了引用计数 ...

  4. C++ malloc、智能指针、类型转换等(三)

    文章目录 malloc.calloc.realloc.alloca 智能指针 shared_ptr weak_ptr unique_ptr auto_ptr 强制类型转换 malloc.calloc. ...

  5. 智能指针的用法shared_ptr

    目录 智能指针 shared_ptr共享的智能指针 shared_ptr的基本用法 1.初始化 reset成员函数 make_shared swap()函数 2. 获取原始指针(get()) 3. 指 ...

  6. 【C++】shared_ptr共享型智能指针详解

    指针是C/C++区别于其他语言的最强大的语法特性,借助指针,C/C++可以直接操纵内存内容.但是,指针的引入也带来了一些使用上的困难,这要求程序员自己必须手动地对分配申请的内存区进行管理. share ...

  7. bartender一行打印两个二次开发_C++ 智能指针和二叉树:图解层序遍历和逐层打印二叉树...

    作者:apocelipes  链接:https://www.cnblogs.com/apocelipes/p/10758692.html 二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不 ...

  8. unique函数_C++智能指针2:(虚?)析构函数(标准与实现的差异)

    只要是有良心的 C++ 教材,总是会苦心孤诣地告诫初学者,在继承关系中,应该把父类的析构函数定义成虚函数.这已然成为一条铁律,如果违背,不仅有内存泄漏的风险,在多继承情况下甚至会出现未定义行为.因此, ...

  9. 智能指针和内存管理小结

    ·概述: 主要是两个库:smart_ptr库和pool库. smart_ptr库主要解决的问题是指针的内存泄漏和垃圾回收问题:pool则是解决内存分配问题. 感觉还是smart_ptr库比较好用一些, ...

最新文章

  1. 【mysql】成绩单表,找到所有成绩都不及格的所有人
  2. ios rsa java_一篇搞定RSA加密与SHA签名|与Java完全同步
  3. perl连接oracle的方法,Perl 连接Oracle 数据库
  4. 在哪里编写写php,php扩展编写
  5. 不容易,今天的成果。
  6. PHP获得文件的md5并检验是否被修改
  7. 职务与职级并行套改表_职务职级并行没有如期而至,2020年会如愿而至吗?
  8. matlab中做出球面和圆柱面,用matlab作出抛物柱面y^2=x和平面x+z=1相交的图形具体步骤...
  9. 中国裁判文书网全网最新爬虫分析
  10. ppt将画好的箭头改为直线
  11. Adobe Photoshop CC 使用过程中图层出现部分图像缺失
  12. 台式机机械硬盘 - 简单快捷的安装
  13. 【原创项目】GC Server 更新
  14. 简单的MediaPlayer+SurfaceView实现视频横竖屏播放
  15. android 斜边_Android -- 一个滑动旋转的弧形菜单
  16. CyclicBarrier让多线程齐步走
  17. 苹果原生二维码扫描器
  18. 视网膜色素上皮细胞研究最新进展
  19. php 加减速 操作,手动挡减挡减速正确方法 加挡先加速减挡先减速
  20. [论文笔记随手] Training with Weighted Sum of Denoising Score Matching Objectives

热门文章

  1. C#使用并行任务库(TPL)
  2. Java + selenium 元素定位(3)之By TagName
  3. 软件GUI测试中的关注点
  4. 杭州恒生数米基金网招聘1-3年本科.NET软件工程师
  5. .NET中的设计模式——一步步发现装饰模式
  6. pytorch---之item()
  7. Eclipse编译时函数报错:Undefined reference to 'pthread_create'
  8. 自动驾驶算法-滤波器系列(五)——高级运动模型在UKF中的应用
  9. c++中的构造函数和析构函数
  10. python文件是否存在_Python判断文件是否存在的三种方法