weak_ptr打破环状引用

转自:http://blog.csdn.net/malong777/article/details/48974559

weak_ptr是一种不控制对象生存周期的智能指针,它指向一个shared_ptr管理的对象...它不会改变shared_ptr的引用计数——《C++ Primer .5th》。很明显,weak_ptr的特点是“弱引用”。有什么用?应用场景是什么地方?

    考虑它的胞兄shared_ptr,每次复制之后引用计数加一,不再指向对象(自身销毁或指向其他对象)时时引用计数减一,减至零值调用所管理资源对象的析构函数。考虑这样一个情况,两个对象各自包含指向彼此的shared_ptr成员,形成环状引用,引用计数永远为1,不能销毁,造成内存泄漏。

//x86_64 win7_64 vs2013 ultimate  
#include <iostream>  
#include <string>  
#include <memory>  
using namespace std;  class A;  
class B;  class A{  
public:  ~A(){ cout << "destroying A\n" ; }  shared_ptr<B> pb;  
};  class B{  
public:  ~B(){ cout << "destroying B\n" ; }  shared_ptr<A> pa;  
};  void test(){  shared_ptr<A> a(new A());  shared_ptr<B> b(new B());  a->pb = b;  b->pa = a;  
}  int main(){  cout << "begin test...\n";  test();  cout << "end test\n";  
}  output:  
begin test...  
end test  
请按任意键继续. . .  

 在函数test()中便是刚才提到的情形,A、B的对象分别被彼此的shared_ptr所引用,离开test()作用域后,A、B对象再也不能被用户访问,因为智能指针a、b被销毁了,但是各自引用计数为1,两个对象的内存再也不会被释放,可怕的内存泄漏就此产生。

 

    那么weak_ptr对此又有帮助呢?考虑如果将B中的智能指针换成weak_ptr<A>,回过头看test()里发生了什么?首先shared_ptr版本的a、b初始化,引用计数各自为1,然后将b赋值给A中的shared_ptr,B对象引用计数变为2,将a赋值给B中的weak_ptr,此操作不改变shared_ptr<A>的引用计数,依旧为1。退出test作用域,a、b析构,B引用计数变为1,A的引用计数为0。A的析构函数被调用,A中的shared_ptr<B>也被销毁,即B的引用计数再次减1变为0,调用B的析构函数。此时,内存已经被全部回收。

 1 class B{  
 2 public:  
 3     ~B(){ cout << "destroying B\n" << endl; }  
 4     weak_ptr<A> pa;  
 5 };  
 6 output:  
 7 begin test...  
 8 destroying A  
 9   
10 destroying B  
11   
12 end test  
13 请按任意键继续.

 实际用用的例子,想象在一个tree结构中,父节点通过一个共享所有权的引用(chared_ptr)引用子节点,同时子节点又必须持有父节点的引用。如果这第二个引用也共享所有权,就会导致一个循环,最终两个节点内存都无法释放。

转载于:https://www.cnblogs.com/13224ACMer/p/6404068.html

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

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

相关文章

百度链接提交php获取状态码,新网站,在百度提交了首页链接,但是一直没有收录,也没有爬虫抓取,怎么回事呢?(悬赏1元) - 搜外SEO问答...

新站前期需要做哪些操作&#xff1a;1、上线前保证网站的内容已经有一定的丰富性&#xff0c;可供爬虫已经有20的主关键词相关的界面或文章&#xff0c;50为最佳。2、新站的标题不要堆彻关键词&#xff0c;以主关键词主关键词描述语句品牌词 这个类型的标题为最佳。3、标题中出…

使用 git-cherry-pick 迁移提交

参考 git-cherry-pick 后续补上

前端js模糊搜索(模糊查询)

1.html结构&#xff1a; <label for"searchShop" class"clear pos-a" style"top:17px;"> <input type"text" id"searchShop" placeholder"场所搜索"> <input type"but…

php代码审计思路,代码审计思路讨论

原标题&#xff1a;代码审计思路讨论前言首先感谢手电筒的建议&#xff0c;建议我从Bluecms来开始学习代码审计。感谢桑桑格&#xff0c;风哥的问题解答。文章主要是写下我自己在代码审计的时候所思所想。当然并不是太过严谨&#xff0c;也有可能存在错误。这里主要是写出了审计…

LinkedHashSet

特点: 有序 , 唯一 底层的数据结构为: 链表和哈希表 , 链表保证有序 , 哈希表保证唯一 import java.util.LinkedHashSet; public class Demo2_LinkedHashSet {/*** param args* LinkedHashSet* 底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象* 因为是Has…

oracle如何自定义类型,Oracle 自定义类型

一、子类型这种类型最简单&#xff0c;类似类型的一个别名&#xff0c;主要是为了对常用的一些类型简单化&#xff0c;它基于原始的某个类型。如&#xff1a;有些应用会经常用到一些货币类型&#xff1a;number(16,2)。如果在全局范围各自定义这种类型&#xff0c;一旦需要修改…

Dubbo源码分析:ThreadPool

定义了通过URL对象作为参数获取Executor对象的get&#xff25;xecutor方法。所有实现ThreadPool接口的类都是基于ThreadPoolExecuotr对象来实现的。 类图 转载于:https://www.cnblogs.com/wspgbw/p/6409933.html

oracle查询并列,【问】oracle-查询各门课程的前2名和后2名

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼成绩表&#xff1a;studentscorecreate table studentScore(id int primary key not null,course varchar2(20),score int,studentname varchar2(20))数据&#xff1a;id course score studentname1 语文 100 张三2 语文 98 李四3 …

MySQL存储过程及触发器

一、存储过程 存储过程的基本格式如下&#xff1a; -- 声明结束符 -- 创建存储过程 DELIMITER $ -- 声明存储过程的结束符 CREATE PROCEDURE pro_test() --存储过程名称(参数列表) BEGIN-- 可以写多个sql语句; -- sql语句流程控制SELECT * FROM employee; END $ -- 结…

asp连接oracle6,asp下用OracleInProcServer完成对Oracle的连接和操作-ASP教程,数据库相关...

< % response.charset"gb2312"tblnamerequest("tb")dim objorasession,objoradbdim strdbuser,strdbpwd,strdbconncall connectdb()sub connectdb() 连接数据库on error resume nextstrdbuser "liujincai" 连接用户名strdbpwd "ljc100…

destoon 短信发送函数及短信接口修改

// $DT在common.inc.php中定义&#xff0c; $CACHE cache_read(module.php); $DT $CACHE[dt]; 从缓存里读取网站配置信息。 //$db 数据库类&#xff0c;$DT 全局配置&#xff0c;$DT[sms] 开启手机短信&#xff0c;$DT_TIME系统时间&#xff0c;$DT_IP 当前ip地址&#xff0…

linux系统电源时钟,linux电源管理的一些梳理

由于项目产品需要过能源之星3.0&#xff0c;所以最近做了一些电源管理低功耗方面的工作&#xff0c;抽个时间正好梳理一下。其实Linux 电源管理非常复杂&#xff0c;牵扯到很多方面&#xff0c;比如系统级的待机、频率电压变换、系统空闲时的处理以及每个设备驱动对于系统待机的…

linux命令行 基础,Linux命令行基础,关于Bash需要知道的一些常识

介绍Linux越来越重要&#xff0c;对于开发者来说学习必要的bash技术必不可少&#xff0c;对运维来说更是如此。学习shell可以参考很多学习材料和图书&#xff0c;比如ChinaUnix论坛网中人大哥总结的《Shell十三问》的帖子&#xff0c;《ABS 指导》(《Advanced Bash-Scripting G…

linux 删除单个创建文件夹,Linux 删除文件夹和创建文件的命令

VS中批注的使用SAL 是 Microsoft 源代码注释语言. 使用源代码批注,可以使代码背后的意图更加清晰. 这些注释还可以使用自动化的静态分析工具更准确地分析代码,显著减少误判.那么什么是批注,举个简单的例子, ...MVVM架构~knockoutjs系列之数组的&dollar;index和&dollar;…

安卓界面组件-文本框

前面三篇文章本质上是围绕着View类进行的。View是安卓UI的基础类&#xff0c;我们的安卓开发“千里之行”是从View开始的。 安卓界面UI有大量的组件&#xff0c;组件的继承和间接继承于View。有一类组件很基本&#xff0c;这就是TextView文本框&#xff0c;作用是显示文本。在T…

linux centos7重启路由命令行,centos7 永久添加静态路由

查看路由表ip route show|column -troute -n永久添加路由vim /etc/sysconfig/network-scripts/route-ens224./ via ../ via重启网络生效systemctl restart networkCentos6C、# vi /etc/sysconfig/static-routes (没有static-routes的话就手动建立一个这样的文件&#xff0c;推荐…

linux内核端口绑定,linux 多网卡bonding 绑定 端口聚合

将多个Linux网络端口绑定为一个&#xff0c;可以提升网络的性能&#xff0c;比如对于备份服务器&#xff0c;需要在一个晚上备份几个T的数据&#xff0c;如果使用单个的千兆网口将会是很严重的瓶颈。其它的应用&#xff0c;比如ftp服务器&#xff0c;高负载的下载网站, 都有类似…

a=a+b和a+=b的区别

1 class Test2 {3 public static void main(String[] args) 4 {5 byte a 127;6 byte b 127;7 byte c(byte)(ab);8 System.out.println(c);9 ab; 10 System.out.println(a); 11 } 12 } 上面的“ab” 操作会先将“…

linux 端口打不开,在线等!!为什么telnet的23端口就是打不开啊

在线等&#xff01;&#xff01;为什么telnet的23端口就是打不开啊发布时间:2007-07-26 19:40:07来源:红联作者:roogger[rootRHEnterprise5 Server]# chkconfig --list |grep telnetekrb5-telnet: offkrb5-telnet: offtelnet: on[rootRHEnterprise5 Server]# netstat -antActiv…

TP框架中的A方法和R方法

ThinkPHP 跨模块调用操作方法&#xff08;A方法与R方法&#xff09;跨模块调用操作方法前面说了可以使用 $this 来调用当前模块内的方法&#xff0c;但实际情况中还经常会在当前模块调用其他模块的方法。ThinkPHP 内置了 A 方法与 R 方法这两个特殊的大写字母方法来处理跨模块调…