智能指针 enable_shared_from_this 陷阱
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 陷阱相关推荐
- 浅析 C++智能指针和 enable_shared_from_this 机制
作者 | 小牛 责编 | 阿哲 头图 | CSDN 下载自视觉中国 来源 | 后端技术小牛说(ID:gh_acfd77ed3228) 今天跟聊一下 BAT 面试 C++ 开发工程师必问的一个考点:智 ...
- c++ 智能指针_详解 C++ 11 中的智能指针
C/C++ 语言最为人所诟病的特性之一就是存在内存泄露问题,因此后来的大多数语言都提供了内置内存分配与释放功能,有的甚至干脆对语言的使用者屏蔽了内存指针这一概念.这里不置贬褒,手动分配内存与手动释放内 ...
- C++智能指针 intrusive_ptr
intrusive_ptr: intrusive_ptr是一个侵入式的引用计数型指针,它可以用于以下两种情形: [1]对内存占用的要求非常严格,要求必须与原始指针一样: [2]现存代码已经有了引用计数 ...
- C++ malloc、智能指针、类型转换等(三)
文章目录 malloc.calloc.realloc.alloca 智能指针 shared_ptr weak_ptr unique_ptr auto_ptr 强制类型转换 malloc.calloc. ...
- 智能指针的用法shared_ptr
目录 智能指针 shared_ptr共享的智能指针 shared_ptr的基本用法 1.初始化 reset成员函数 make_shared swap()函数 2. 获取原始指针(get()) 3. 指 ...
- 【C++】shared_ptr共享型智能指针详解
指针是C/C++区别于其他语言的最强大的语法特性,借助指针,C/C++可以直接操纵内存内容.但是,指针的引入也带来了一些使用上的困难,这要求程序员自己必须手动地对分配申请的内存区进行管理. share ...
- bartender一行打印两个二次开发_C++ 智能指针和二叉树:图解层序遍历和逐层打印二叉树...
作者:apocelipes 链接:https://www.cnblogs.com/apocelipes/p/10758692.html 二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不 ...
- unique函数_C++智能指针2:(虚?)析构函数(标准与实现的差异)
只要是有良心的 C++ 教材,总是会苦心孤诣地告诫初学者,在继承关系中,应该把父类的析构函数定义成虚函数.这已然成为一条铁律,如果违背,不仅有内存泄漏的风险,在多继承情况下甚至会出现未定义行为.因此, ...
- 智能指针和内存管理小结
·概述: 主要是两个库:smart_ptr库和pool库. smart_ptr库主要解决的问题是指针的内存泄漏和垃圾回收问题:pool则是解决内存分配问题. 感觉还是smart_ptr库比较好用一些, ...
最新文章
- 【mysql】成绩单表,找到所有成绩都不及格的所有人
- ios rsa java_一篇搞定RSA加密与SHA签名|与Java完全同步
- perl连接oracle的方法,Perl 连接Oracle 数据库
- 在哪里编写写php,php扩展编写
- 不容易,今天的成果。
- PHP获得文件的md5并检验是否被修改
- 职务与职级并行套改表_职务职级并行没有如期而至,2020年会如愿而至吗?
- matlab中做出球面和圆柱面,用matlab作出抛物柱面y^2=x和平面x+z=1相交的图形具体步骤...
- 中国裁判文书网全网最新爬虫分析
- ppt将画好的箭头改为直线
- Adobe Photoshop CC 使用过程中图层出现部分图像缺失
- 台式机机械硬盘 - 简单快捷的安装
- 【原创项目】GC Server 更新
- 简单的MediaPlayer+SurfaceView实现视频横竖屏播放
- android 斜边_Android -- 一个滑动旋转的弧形菜单
- CyclicBarrier让多线程齐步走
- 苹果原生二维码扫描器
- 视网膜色素上皮细胞研究最新进展
- php 加减速 操作,手动挡减挡减速正确方法 加挡先加速减挡先减速
- [论文笔记随手] Training with Weighted Sum of Denoising Score Matching Objectives
热门文章
- C#使用并行任务库(TPL)
- Java + selenium 元素定位(3)之By TagName
- 软件GUI测试中的关注点
- 杭州恒生数米基金网招聘1-3年本科.NET软件工程师
- .NET中的设计模式——一步步发现装饰模式
- pytorch---之item()
- Eclipse编译时函数报错:Undefined reference to 'pthread_create'
- 自动驾驶算法-滤波器系列(五)——高级运动模型在UKF中的应用
- c++中的构造函数和析构函数
- python文件是否存在_Python判断文件是否存在的三种方法