std::shared_ptr

  在std::shared_ptr被引入之前,C++标准库中实现的用于管理资源的智能指针只有std::auto_ptr一个而已。std::auto_ptr的作用非常有限,因为它存在被管理资源的所有权转移问题。这导致多个std::auto_ptr类型的局部变量不能共享同一个资源,这个问题是非常严重的哦。因为,我个人觉得,智能指针内存管理要解决的根本问题是:一个堆对象(或则资源,比如文件句柄)在被多个对象引用的情况下,何时释放资源的问题。何时释放很简单,就是在最后一个引用它的对象被释放的时候释放它。关键的问题在于无法确定哪个引用它的对象是被最后释放的。std::shared_ptr确定最后一个引用它的对象何时被释放的基本想法是:对被管理的资源进行引用计数,当一个shared_ptr对象要共享这个资源的时候,该资源的引用计数加1,当这个对象生命期结束的时候,再把该引用技术减少1。这样当最后一个引用它的对象被释放的时候,资源的引用计数减少到0,此时释放该资源。下边是一个shared_ptr的用法例子:#include <iostream>  
#include <memory>  class Woman;  
class Man{  
private:  std::weak_ptr<Woman> _wife;  //std::shared_ptr<Woman> _wife;  
public:  void setWife(std::shared_ptr<Woman> woman){  _wife = woman;  }  void doSomthing(){  if(_wife.lock()){  }  }  ~Man(){  std::cout << "kill man\n";  }  
};  class Woman{  
private:  //std::weak_ptr<Man> _husband;  std::shared_ptr<Man> _husband;  
public:  void setHusband(std::shared_ptr<Man> man){  _husband = man;  }  ~Woman(){  std::cout <<"kill woman\n";  }  
};  int main(int argc, char** argv){  std::shared_ptr<Man> m(new Man());  std::shared_ptr<Woman> w(new Woman());  if(m && w) {  m->setWife(w);  w->setHusband(m);  }  return 0;  
}  在Man类内部会引用一个Woman,Woman类内部也引用一个Man。当一个man和一个woman是夫妻的时候,他们直接就存在了相互引用问题。man内部有个用于管理wife生命期的shared_ptr变量,也就是说wife必定是在husband去世之后才能去世。同样的,woman内部也有一个管理husband生命期的shared_ptr变量,也就是说husband必须在wife去世之后才能去世。这就是循环引用存在的问题:husband的生命期由wife的生命期决定,wife的生命期由husband的生命期决定,最后两人都死不掉,违反了自然规律,导致了内存泄漏。解决std::shared_ptr循环引用问题的钥匙在weak_ptr手上。weak_ptr对象引用资源时不会增加引用计数,但是它能够通过lock()方法来判断它所管理的资源是否被释放。另外很自然地一个问题是:既然weak_ptr不增加资源的引用计数,那么在使用weak_ptr对象的时候,资源被突然释放了怎么办呢?呵呵,答案是你根本不能直接通过weak_ptr来访问资源。那么如何通过weak_ptr来间接访问资源呢?答案是:在需要访问资源的时候weak_ptr为你生成一个shared_ptr,shared_ptr能够保证在shared_ptr没有被释放之前,其所管理的资源是不会被释放的。创建shared_ptr的方法就是lock()方法。细节:shared_ptr实现了operator bool() const方法来判断一个管理的资源是否被释放。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity 里调试native code

因项目需要&#xff0c;需要调试dll工程代码。 把生成的debug dll和pdb拷贝进unity的plugins工程&#xff0c;遇到 断点无法进入&#xff0c;修改下调试信息格式&#xff0c;OK。 转载于:https://www.cnblogs.com/marcher/p/10191521.html

将自己写的windows服务加入到windows集群中

最近发现windows集群能进行很多自定义&#xff0c;比如在集群中加入自己编写的服务。 能自定义的可不少&#xff0c;截个图&#xff1a; 本次演示中&#xff0c;只想用“通用服务”这个类型。 先列下步骤编写一个记录时间的Windows服务&#xff0c;这个服务会每隔1秒钟写入本地…

RTC实时时钟实验(低功耗、纽扣电池供电)

目录I.MX6U RTC 简介硬件原理分析实验程序编写修改文件MCIMX6Y2.h编写实验程序编译下载验证编写Makefile 和链接脚本编译下载实时时钟是很常用的一个外设&#xff0c;通过实时时钟我们就可以知道年、月、日和时间等信息。因此在需要记录时间的场合就需要实时时钟&#xff0c;可…

Python(21)_input用户交互

name input("请输入你的名字&#xff1a;") age input("请输入你的年龄&#xff1a;") print("我的名字是&#xff1a;"name" 年龄是&#xff1a;"age) #print(name) #print(age) 这是在本地调试的结果。因为程序是在远程服务器上执…

多点电容触摸屏实验

目录多点电容触摸简介硬件原理分析实验程序编写编译下载验证编写Makefile 和链接脚本编译下载随着智能手机的发展&#xff0c;电容触摸屏也得到了飞速的发展。相比电阻触摸屏&#xff0c;电容触摸屏有很多的优势&#xff0c;比如支持多点触控、不需要按压&#xff0c;只需要轻轻…

博客园自动添加版权说明,自动添加文章链接

功能&#xff1a; 1.给每一篇文章开头加上版权说明&#xff1b; 2.自动获取当前文章地址&#xff1b; 3.做了装饰。 将以下代码放在页首Html代码内即可&#xff1a; <script type"text/javascript"> var setMyBlog {setCopyright: function() {//设置版权信息…

如何添加地图控件到Windows Phone 8的页面中

原文 如何添加地图控件到Windows Phone 8的页面中 本主题介绍了各种方法来添加一个地图控件到Windows Phone 8的项目。该地图控件在Windows Phone的SDK 8.0的库的一部分。因为地图的控制是不是在内存中的核心控制&#xff0c;它必须被正确引用&#xff0c;然后才能使用它。您还…

LCD背光调节实验

目录LCD 背光调节简介硬件原理分析实验程序编写编译下载验证编写Makefile 和链接脚本编译下载不管是使用显示器还是手机&#xff0c;其屏幕背光都是可以调节的&#xff0c;通过调节背光就可以控制屏幕的亮度。在户外阳光强烈的时候可以通过调高背光来看清屏幕&#xff0c;在光线…

Mercurial(Hg)基本操作

Mercurial(Hg)基本操作 来源 https://www.cnblogs.com/gb2013/archive/2012/05/18/Mercurial_Basic.html Mercurial简介 Mercurial是一款非常优秀的分布式版本控制系统(DCVS)&#xff0c;具有高效率、跨平台、可扩展、使用简便且开源等优点&#xff0c;是目前最为流行的版本控制…

SPI实验

目录SPI & ICM-20608 简介SPI 简介SPI四线SPI四种工作模式SPI时序图I.MX6U ECSPI 简介ICM-20608 简介硬件原理分析实验程序编写编译下载验证编写Makefile 和链接脚本编译下载同I2C 一样&#xff0c;SPI 是很常用的通信接口&#xff0c;也可以通过SPI 来连接众多的传感器。相…

Office安装源损坏

故障现象&#xff1a;安装office时&#xff0c;提示“Microsoft office安装程序无法继续&#xff0c;因为安装源错误”。解决方案&#xff1a;1.从Microsoft下载中心&#xff0c;下载最新版本Microsoft XML Parser(MSXML)安装。2.重新注册Msxml3.dll文件&#xff0c;运行Regsvr…

filter-mutate过滤插件

之前的nginx日志使用grok匹配&#xff0c;但是后来发现nginx的日志中每个值之间都使用了分隔符"|",这下就可以使用mutate来分隔出每个字段的含义&#xff0c;同时还减少了运算。 描述 mutate过滤器允许您对字段执行常规突变。您可以重命名&#xff0c;删除&#xff0…

ADC实验(读取引脚电压值)

目录ADC 简介什么是ADCI.MX6ULL ADC 简介ADC寄存器介绍配置步骤硬件原理分析实验程序编写编译下载验证编写Makefile 和链接脚本编译下载ADC 是一种常见的外设&#xff0c;你可以在STM32 上见到它&#xff0c;在I.MX 6ULL 上依然能看到它的存在。通过读取GPIO 引脚的高低电平我们…

Linux CAN 驱动实验

目录CAN 协议简析何为CANCAN 电气属性显隐性电平接线端接电阻速度距离CAN 协议1、数据帧2、遥控帧3、错误帧4、过载帧5、帧间隔CAN 速率I.MX6ULL FlexCAN 简介硬件原理图分析实验程序编写修改设备树使能Linux 内核自带的FlexCAN 驱动FlexCAN 测试检查CAN 网卡设备是否存在移植i…

git 常用的撤销操作

git 开发时的使用流程&#xff0c;从同事那里学习的&#xff0c; 第一步&#xff0c;先建立一个新的分支&#xff0c;可以在GITLAB或通过命令git checkout -b newbranch 或通过IDE插件 第二步&#xff0c;让项目切换到该分支&#xff0c;然后在这个分支上进行开发 第三个&#…

MySQL存储引擎MyISAM和 InnoDB

2019独角兽企业重金招聘Python工程师标准>>> 区别 事务处理MyISAM强调性能,但是不提供事务支持InnoDB提供事务支持,外部键等CURD操作如果执行大量SELECT,MyISAM更合适(读)如果执行大量INSERT/UPDATE,InnoDB更合适(写)DELETE FROM table时&#xff0c;InnoDB不会重新…

Luogu 4721 【模板】分治 FFT

还不会这题的多项式求逆的算法。 发现每一项都是一个卷积的形式&#xff0c;那么我们可以使用$NTT$来加速&#xff0c;直接做是$O(n^2logn)$的&#xff0c;我们考虑如何加速转移。 可以采用$cdq$分治的思想&#xff0c;对于区间$[l, r]$中的数&#xff0c;先计算出$[l, mid]$中…

根文件系统构建(Buildroot 方式)

目录何为buildroot&#xff1f;buildroot 简介buildroot 下载buildroot 构建根文件系统配置buildroot编译buildrootbuildroot 根文件系统测试buildroot 第三方软件和库的配置buildroot 下的busybox 配置busybox 配置busybox 中文字符的支持编译busybox根文件系统测试前面我们学…

Kernel panic -not syncing:Attempted to kill init!

DELL R210II安装RHEL后启动系统正常&#xff0c;关机再装磁盘阵列卡接好磁盘阵列&#xff0c;开机后CTRLR进入界面配置RAID5。启动后出现错误&#xff1a; Kernel panic -not syncing:Attempted to kill init! 解决过程&#xff1a;1、强行关机&#xff0c;再重启进入系统选择界…

根文件系统构建(Yocto方式)

本章有独立的教程&#xff0c;请参考《【正点原子】I.MX6U Yocto 构建根文件系统V1.0.pdf》&#xff01;