为什么使用enable_shared_from_this——shared_ptr两类错误
在使用C++实现弱回调时,订阅者应当维护一系列发布者的weak_ptr,而发布者注册回调时要传出this的shared_ptr指针,流行的实现方法是使用std::enable_shared_from_this。
初次学习这个模板类时疑问了一下为什么不能依赖this直接产生一个shared_ptr?实验发现shared_ptr的固有特性使这样做不是很方便。
借用MSDN的example:
// std_memory_shared_from_this.cpp
// compile with: /EHsc
#include <memory>
#include <iostream> using namespace std; struct base : public std::enable_shared_from_this<base>
{
int val; shared_ptr<base> share_more()
{
return shared_from_this();
//return make_shared<base>(*this); //err1
//return shared_ptr<base>(this); //err2
}
}; int main()
{
auto sp1 = make_shared<base>();
auto sp2 = sp1->share_more(); sp1->val = ;
cout << "sp2->val == " << sp2->val << endl; return ;
}
尝试了两种写法都出现了错误的行为,分别解释。
err1中,输出结果为0,make_shared实际可以看作为了完全封装new而给shared_ptr的一个factory,作用是产生新对象,那么参数*this作为复制构造的参数,实际已经和this没有关系了。
err2中,输出为3,但程序结束时触发了断点,这也是使用智能指针应当注意的——复制行为不要依赖裸指针。
通过代码
cout << "sp2's ref count == " << sp2.use_count() << endl;
可以发现,sp2引用计数为1,因为产生它时参数为裸指针this,,它是一个新的智能指针,这就产生了问题,sp1,sp2两个智能指针同时指向一个堆对象——析构行为时会delete两次!
所以依赖shared_ptr我们很难从对象内部传出指向自己的指针指针,use std::enable_shared_from_this。
为什么使用enable_shared_from_this——shared_ptr两类错误的更多相关文章
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- java运行代码连接mysql时提示:找不到类错误
使用IntelliJ IDEA Community Edition进行代码编写.. 使用一下代码连接mysql时出现了:java.lang.ClassNotFoundException: com.my ...
- JDBC连接时出现的两个错误
这两个错误都是因为版本的更新导致的: 错误代码: package FirstTest; import java.sql.*; public class FirstJDBC { public stati ...
- 显著水平|区间估计|假设检验|显著性|第一类错误|Ⅱ类错误|β错误|t检验|连续性矫正|二项分布的假设检验|样本百分率|
第三章 假设检验 区间估计与假设检验的基本区别? 上一章中讨论了置信区间的估计方法.它是利用样本数据,以抽样总体的分布为理论基础,用一定的概率保证来计算出原总体中未知参数的区间范围.特别值得注意的是: ...
- C++ 11 智能指针(shared_ptr)类成员函数详解
C++ 11 模板库的 <memory> 头文件中定义的智能指针,即 shared_ptr 模板类,用来管理指针的存储,提供有限的内存回收函数,可同时与其他对象共享该管理功能. share ...
- delphi 创建DBASE和FOXPRO两类DBF数据文件的差异
delphi 创建DBASE和FOXPRO两类DBF数据文件的差异,主要有几点: 1.创建方法不同 DBASE的创建方法: Self.Table1.Close; Self.Table1.Active ...
- Java 网络编程(二) 两类传输协议:TCP UDP
链接地址:http://www.cnblogs.com/mengdd/archive/2013/03/09/2951841.html 两类传输协议:TCP,UDP TCP TCP是Transfer C ...
- Laravel用post提交表单常见的两个错误
最近在自学Laravel,测试用post方法提交表单时碰到两个错误: 1.获取传入的值时,报错如下图所示: 在stackFlow找答案时各种解释都有,但认真读一下报错信息,意思大概是:获取Http传入 ...
- MT【284】构造函数的导数的两类题型
第一类: 已知定义在$R$上的奇函数$f(x),f(-1)=0,$当$x>0$时,$xf^{'}(x)-f(x)<0,$则$f(x)>0$的解集为____ 第二类: 已知函数$f(x ...
随机推荐
- iOS开发——delegate的相关警告
警告:Assigning to 'id<...Delegate>' from incompatible type '...ViewController *const_strong' 解决方 ...
- iOS开发——浅谈构架与用户体验
工作不是千篇一律的重复,从中寻找乐趣才是我们应该做的. 作为一名码农,做过几个项目,每次做项目的时候都会自己构思,如果完全是我自己设计,会怎么去设计?心里一直没有满意的答案,不管怎么布局,好像都感觉差 ...
- 【Xilinx-Petalinux学习】-05-OpenCV程序测试
占位, 通过上一次编译的opencv库,运行程序,实现图像处理
- 使用python爬虫抓站的一些技巧总结:进阶篇
Reference:http://python.jobbole.com/82000/ 一.gzip/deflate支持 现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页 ...
- Js把IE COM数组列表转换成数组
今天写组件的时候遇到一个问题,就是当我需要对获取到的对象列表进行删减的时候,发现没有合适的方法,比如: //获取图片列表 var imgs = document.getElementsByTagNam ...
- 为什么ajax 必须同源,same origin policy
ajax 所有请求都会附带主域的cookie, 若没有同源策略,攻击者就可以获取你的cookie,状态.
- event.returnValue和return false的区别
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Mysql中常见索引操作
- windows下安装php5.2.*,php5.3.*,php5.4.*版本的memcache扩展
注:如使用集成环境成功率低,请自行配置php apache,表示win7下wamp php5.4.3基础上配置拓展,成功率极低.费时. 拓展安装调试方法: 编写调试php文件 <?php me ...
- jQuery DataTables and ASP.NET MVC Integration
part 1 : http://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Pa ...