C++11:shared_ptr循环引用问题

一、shared_ptr的弊端 

struct Listnode
{int _val;std::shared_ptr<Listnode> _prev;std::shared_ptr<Listnode> _next;Listnode(int val ):_val(val),_prev(nullptr),_next(nullptr){}~Listnode(){cout << "~Listnode()" << endl;}
};
int main()
{std::shared_ptr<Listnode> n1(new Listnode(20));std::shared_ptr<Listnode> n2(new Listnode(10));n1->_next = n2; n2->_prev = n1;return 0;
}

 如上的情况就出现了循环引用,两个对象相互掣肘。

1. node1和node2两个智能指针对象指向两个节点,引用计数变成1,我们不需要手动delete。
2. node1的_next指向node2,node2的_prev指向node1,引用计数变成2。
3. node1和node2析构,引用计数减到1,但是_next还指向下一个节点。但是_prev还指向上一个节点。
4. 也就是说_next析构了,node2就释放了。
5. 也就是说_prev析构了,node1就释放了。
6. 但是_next属于node的成员,node1释放了,_next才会析构,而node1由_prev管理,_prev属于node2成员,所以这就叫循环引用,谁也不会释放。
展开来讲:

两个对象的引用计数都变为2,当要进行析构时就陷入了循环引用。

1、左边节点要想析构就得等右边的_prev去调用析构。

2、右边节点被delete时去调用_prev.

3、而右边节点被析构需要左边节点的_next去调用析构

4、左边节点被delete时去调用_prev

5、左边节点要想析构就得等右边的_prev去调用析构。

到这里就以及死循环了。

二、weak

它的特点就是不增加引用计数,专门用于shared_ptr出现循环引用的情况。

struct Listnode
{int _val;std::weak_ptr<Listnode> _prev;std::weak_ptr<Listnode> _next;Listnode(int val ):_val(val){}~Listnode(){cout << "~Listnode()" << endl;}
};
int main()
{std::shared_ptr<Listnode> n1(new Listnode(20));std::shared_ptr<Listnode> n2(new Listnode(10));n1->_next = n2; n2->_prev = n1;return 0;
}

 2.1模拟实现

struct Listnode
{int _val;gaz::weak_ptr<Listnode> _prev;gaz::weak_ptr<Listnode> _next;Listnode(int val ):_val(val){}~Listnode(){cout << "~Listnode()" << endl;}
};
int main()
{gaz::shared_ptr<Listnode> n1(new Listnode(20));gaz::shared_ptr<Listnode> n2(new Listnode(10));n1->_next = n2; n2->_prev = n1;return 0;
}
template<class T>class weak_ptr{public://RALLweak_ptr():_ptr(nullptr){}weak_ptr(const shared_ptr<T>& sp){_ptr = sp.get();}weak_ptr<T>& operator=(const shared_ptr<T>& sp){_ptr = sp.get();return *this;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}private:T* _ptr;};

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

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

相关文章

翻译《The Old New Thing》 - How do I cover the taskbar with a fullscreen window?

How do I cover the taskbar with a fullscreen window? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20050505-04/?p35703 Raymond Chen 2005年5月5日 如何用全屏窗口覆盖任务栏&#xff1f; 很多时候&#xff0c;人们总是想得太多。…

2012NOIP普及组真题 1. 质因数分解

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1957 核心思想&#xff1a; 1、题中提到&#xff1a;n是两个不同的质数的乘积&#xff0c;求最大的质数。假设 n a ∗ b na*b na∗b&#xff0c;b为最大的质因数&#xff0c;则 a为n最…

Java高级开发者的面试问题及其答案

1. 在Java中&#xff0c;怎样理解并发与并行&#xff1f; 答案&#xff1a; 并发&#xff08;Concurrency&#xff09;和并行&#xff08;Parallelism&#xff09;是多线程编程的两个核心概念&#xff0c;它们在Java中有着重要的应用。 并发指的是多个任务能在重叠的时间段内…

使用 scikit-learn 进行机器学习的基本原理-2

介绍 scikit-learn 估计器对象 每个算法都通过“Estimator”对象在 scikit-learn 中公开。 例如&#xff0c;线性回归是&#xff1a;sklearn.linear_model.LinearRegression 估计器参数&#xff1a;估计器的所有参数都可以在实例化时设置&#xff1a; 拟合数据 让我们用 nump…

springboot整合mqtt实现android推送功能

1、mqtt服务器使用emqx EMQX: The Worlds #1 Open Source Distributed MQTT Broker 2、下载安装 下载地址&#xff1a; Download EMQX 选择系统&#xff0c;版本&#xff0c;安装方法 3、springboot连接mqtt服务方法&#xff1a; 引包&#xff1a; <dependency><…

[附源码]SpringBoot+Vue网盘项目_仿某度盘

视频演示 [附源码]SpringBootVue网盘项目_仿某度盘 功能介绍 支持秒传支持视频音频播放、拖拽进度条、倍速播放等支持图片预览&#xff0c;旋转&#xff0c;放大支持多人一起上传&#xff0c;共享上传进度&#xff08;例如a上传苍老师学习资料到50%&#xff0c;突然b也上传苍老…

uniapp + uView动态表单校验

项目需求&#xff1a;动态循环表单&#xff0c;并实现动态表单校验 页面&#xff1a; <u--form label-position"top" :model"tmForm" ref"tmForm" label-width"0px" :rulesrules><div v-for"(element, index) in tmForm…

Docker依旧没有过时

【A】Docker 是一种开源的容器化平台&#xff0c;它允许开发人员将应用程序及其所有依赖项打包到一个统一的容器中&#xff0c;并在不同环境中进行部署和运行。以下是 Docker 的一些基本概念和优势&#xff1a; 容器&#xff1a;Docker 使用容器来隔离应用程序和其依赖项&#…

【信息系统项目管理师知识点速记】范围管理:确认范围

9.7 确认范围 确认范围是正式验收已完成的项目可交付成果的过程。其主要作用是使验收过程具有客观性,通过确认每个可交付成果来提高最终产品、服务或成果获得验收的可能性。确认范围过程应根据需要在整个项目期间定期开展。 1. 确认范围的步骤 确认范围应贯穿项目始终。一般…

低功耗数字IC后端设计实现典型案例| UPF Flow如何避免工具乱用Always On Buffer?

下图所示为咱们社区低功耗四核A7 Top Hierarchical Flow后端训练营中的一个案例&#xff0c;设计中存在若干个Power Domain&#xff0c;其中Power Domain2(简称PD2)为default Top Domain&#xff0c;Power Domain1&#xff08;简称PD1&#xff09;为一个需要power off的domain&…

mac/windows下安装docker,minikube

1、安装docker Get Started | Docker 下载安装docker 就行 启动后&#xff0c;就可以正常操作docker了 使用docker -v 验证是否成功就行 2、安装minikube&#xff0c;是基于docker-desktop的 2.1、点击设置 2.2、选中安装&#xff0c;这个可能需要一点时间 这样安装后&…

JavaScript实现在线屏幕录制

本文主要介绍在线屏幕录制 Demo Its sole method is MediaDevices.getDisplayMedia() !移动端暂不支持 环境要求 新版本 Chrome,Edge,Firefox 桌面浏览器 常见问题 1. navigator.mediaDevices为undefined 在不安全的情况下&#xff0c;navigator.mediaDevices是undefine…

机器学习实战 —— 工业蒸汽量预测(二)

目录 文章描述背景描述数据说明数据来源实战内容2.数据特征工程2.1数据预处理和特征处理2.1.1 异常值分析2.1.2 归一化处理2.1.3 特征相关性 2.2 特征降维2.2.1 相关性初筛2.2.2 多重共线性分析2.2.3 PCA处理降维 文章描述 数据分析&#xff1a;查看变量间相关性以及找出关键变…

面试经典算法题之双指针专题

力扣经典面试题之双指针 ( 每天更新, 每天一题 ) 文章目录 力扣经典面试题之双指针 ( 每天更新, 每天一题 )验证回文串收获 392. 判断子序列 验证回文串 思路 一: 筛选 双指针验证 class Solution { public:bool isPalindrome(string s) {// 所有大写字母 > 小写 去除非字母…

深度学习中的模块化设计

模块化设计在机器学习和深度学习领域中是一个重要的概念&#xff0c;特别是在构建和改进像编码器-解码器这样的复杂模型时。以下是模块化设计如何帮助快速集成最新研究成果的一些关键点&#xff1a; 即插即用&#xff1a;模块化设计允许研究人员将新的研究成果如新的注意力机制…

掌握JavaScript面向对象编程核心密码:深入解析JavaScript面向对象机制对象基础、原型模式与继承策略全面指南,高效创建高质量、可维护代码

ECMAScript&#xff08;简称ES&#xff0c;是JavaScript的标准规范&#xff09;支持面向对象编程&#xff0c;通过构造函数模拟类&#xff0c;原型链实现继承&#xff0c;以及ES6引入的class语法糖简化面向对象开发。对象可通过构造函数创建&#xff0c;使用原型链共享方法和属…

max各种相机导出到ue4匹配镜头的工具集

总览 rollout export_UE4Cam_v2 "导出UE4Cam_v2:半自动" width:200 height:120(HyperLink explain "在打开的max文件中使用" pos:[25,12] width:200 height:15 color:(color 255 155 0) GroupBox grp1 "要导出的相机名" pos:[5,28] width:179 …

一个单例模式中使用std::unique_ptr引起的莫名其妙的COFF损坏的问题(未解决)

使用static std::unique_ptr和static std::shared_ptr都不行struct IElementAgendaEvents {//! Called to allow listeners to modify the agenda by adding/removing entries before applying tool operation. Return true if entries added or invalidated.virtual bool …

如何使用Scrapy和Python 3爬取网页

简介 网络爬虫&#xff0c;通常称为网络爬行或网络蜘蛛&#xff0c;是以编程方式浏览一系列网页并提取数据的行为&#xff0c;是处理网络数据的强大工具。 通过使用网络爬虫&#xff0c;您可以挖掘有关一组产品的数据&#xff0c;获取大量文本或定量数据以进行分析&#xff0…

1、FreeCAD概述与架构

FreeCAD介绍 FreeCAD的诞生&#xff1a;2002年10月29日&#xff0c;由Jrgen Riegel上传了版本0.0.1的初始上传。FreeCAD的维基百科页面显示&#xff0c;FreeCAD基本上是由不同强大的库组成的集合&#xff0c;其中最重要的是openCascade&#xff0c;用于管理和构建几何体&#x…