weak_ptr如何能做到解决循环引用又能传递参数呢?

news2024/12/25 1:46:43

引子:今天在看CLR via C#的时候看到C#的垃圾回收算法--引用跟踪算法的时候想到以下几个问题。

一、引用计数法存在的问题

一般引用计数法存在的问题就是不好处理循环引用的问题,但是C++不是有weak_ptr吗?

这个引用跟踪的垃圾回收算法看起来还蛮复杂的,跟引用计数法比起来性能消耗估计得大的更多。难不成是引用计数法还有解决不了的问题?于是便用C++的智能指针想出了一种场景:就是既有循环又得传递参数的情形,代码如下所示:

class A;
class B;
class A
{
public:
	std::shared_ptr<B> ptrb;
	int k = 1;
};
class B
{
public:
	std::weak_ptr<A> ptra;
	int k = 2;
};
//可以解决循环引用
void testPtr()
{
	std::shared_ptr<B> ptrB(new B());
	std::shared_ptr<A> ptrA(new A());
	ptrA->ptrb = ptrB;
	ptrB->ptra = ptrA;
}
//但是还想能解决参数传递,似乎就不行了
void testRef(std::shared_ptr<B>& b)
{
	std::shared_ptr<B> ptrB(new B());
	std::shared_ptr<A> ptrA(new A());
	ptrA->ptrb = ptrB;
	ptrB->ptra = ptrA;
	b = ptrB;
}
int main()
{
	std::shared_ptr<B> b;
	testRef(b);
	std::cout << b->ptra.lock()->k << std::endl;//在这就出错了,该空间被释放掉了
	return 0;
}

上面的代码构造了一个即想要解决循环引用又想解决对象的参数传递,但不幸的是在参数传递的时候因为弱指针指向的空间为空导致异常。这么一想引用计数好像还确实比较麻烦,有些极端的情况解决不了。

二、C#中的循环引用
class A
{
    public B ptrb;
    public int k=1;
}
class B
{
    public A ptra;
    public int k = 2;
}
static class Program
{ 
    static void tesrRef(out A aptr)
    {
        A a = new A();
        B b = new B();
        a.ptrb = b;
        b.ptra = a;
        aptr = a;
    }
    public static int Main()
    {
        A a;
        tesrRef(out a);
        Console.WriteLine(a.ptrb.k);
        return 0;
    }
}

然后试了下用C#解决循环引用确实很不错,即使传递参数也不会出现啥问题。

然后看看CLR via C#中对引用跟踪法的解释:

然后简单凭个人理解了下跟引用跟踪法比引用计数法厉害的地方(可能理解的还不太准确,先暂时这么说服自己):引用跟踪法可以把一个根中的所有成员变量一起作为根拿出来去引用开辟在托管堆中对象,因此在一个根不引用托管堆中对象的对象的时候会让其成员变量根也一起不引用其所对应的托管堆对象,而这正是引用计数法做不到的。引用计数法只能让自身的根不引用自身的堆对象而不能让自身的成员变量不去引用堆对象因此才会造成循环引用问题。

本文参考:

智能指针之弱引用的指针

New book: CLR via C#, Fourth Edition | Microsoft Learn

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

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

相关文章

vivado xsim 终端 模拟

只模拟的话直接终端运行会快很多 计数器举例 mkdir srccounter.v module counter(input wire clk,input wire rst_n,output reg[31:0] cnt ); always (posedge clk or negedge rst_n)if(!rst_n)cnt < 31h0;elsecnt < cnt1;endmodule tb.v module tb; wire[31:0] out…

C语言编译器(C语言编程软件)完全攻略

介绍常用C语言编译器的安装、配置和使用。 常用的C语言编译器&#xff08;编程软件&#xff09;介绍&#xff0c;同时附带下载地址、详细的安装教程和使用教程。我们还对比了不同C语言编译器&#xff08;C语言编程软件&#xff09;的优缺点&#xff0c;让初学者知道该如何选择…

WPF 使用矢量字体图标

矢量字体图标 在WPF项目中经常需要显示图标&#xff0c;但是项目改动后&#xff0c;有时候需要替换和修改图标&#xff0c;这样非常麻烦且消耗开发和美工的时间。为了快速开发项目&#xff0c;节省项目时间&#xff0c;使用图标矢量字体图标是一个非常不错的选择。 矢量字体图标…

Java Swing手搓童年坦克大战游戏(I)

前言 业余偶尔对游戏有些兴趣&#xff0c;不过这样的时代&#xff0c;硬件软件飞速进步&#xff0c;2D游戏画面都无比精美&#xff0c;之前的8bit像素游戏时代早就过去了&#xff0c;不过那时候有许多让人印象深刻的游戏比如魂斗罗、超级玛丽、坦克大战(Battle City)等等。 学…

案例102:基于微信小程序的旅游社交管理系统设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

Robot Operating System 2: Design, Architecture, and Uses In The Wild

Robot Operating System 2: Design, Architecture, and Uses In The Wild (机器人操作系统 2&#xff1a;设计、架构和实际应用) 摘要&#xff1a;随着机器人在广泛的商业用例中的部署&#xff0c;机器人革命的下一章正在顺利进行。即使在无数的应用程序和环境中&#xff0c;也…

C语言基础知识(5):TCP网络编程

TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构&#xff0c;当应用程序采用 TCP 发送消息时&#xff0c;虽然可以保证发送的顺序&#xff0c;但还是犹如没有任何间隔的数据流发送给接收端。TCP 为提供可靠性传输&#xff0c;实行“顺序控制”或“重发控制”机制。此…

学习笔记——C++中的循环结构 while语句

while循环语句 作用&#xff1a;满足循环条件&#xff0c;执行循环语句 语法&#xff1a;while&#xff08;循环条件&#xff09;{循环语句} 解释&#xff1a;只要循环条件的结果为真&#xff0c;就执行循环语句 以打印0-9这十个数字为例&#xff0c;特别需要注意的是&…

MySQL之视图索引执行计划

目录 一.视图 二.执行计划 2.1.什么是执行计划 2.2.执行计划的作用 三.使用外连接、内连接和子查询进行举例 四.思维导图 好啦今天就到这里了哦&#xff01;&#xff01;&#xff01;希望能帮到你哦&#xff01;&#xff01;&#xff01; 一.视图 含义 &#xff1a;在数…

Nginx快速入门:Nginx实现高可用|结合keepalived实现主备节点(九)

0. 引言 在生产中我们要尽可能避免单点故障&#xff0c;nginx也不例外&#xff0c;因此搭建主备节点必不可少&#xff0c;今天我们来学习下如何利用keepalived实现主备 1. keepalived简介 keepalived 是一个LINUX系统中开源的负载均衡和故障转移软件&#xff0c;它主要用于高…

解决 POST http://x.x.x.x:8000/aaa/ net::ERR_CONNECTION_TIMED_OUT

记录一下我遇到的问题和解决办法 我的项目前后端分离&#xff0c;在前端用的vue访问后端时连接不上后端&#xff0c;一切操作都触发不了后端&#xff0c;数据也传不到后端去&#xff1b; 原因&#xff1a;url有问题&#xff0c;url地址写的不是本机&#xff0c;所以导致连接超…

Nginx快速入门:worker、master进程的作用和热部署原理(十)

0. 引言 我们通过查询nginx进程&#xff0c;可以发现nginx有两个进程&#xff1a;worker和master。一个程序启动了两个进程&#xff0c;那么这两个进程的作用和区别是什么呢&#xff1f;nginx又是如何利用这两个进程进行工作的呢&#xff1f;nginx不停机热部署又是如何实现的&…

如何使用UUP从windows更新服务器下载windows10原版镜像

UUP是指Windows 10中的一种更新技术&#xff0c;全称为Unified Update Platform。UUP的目标是提供更快、更高效的更新体验&#xff0c;它通过增量更新的方式来更新操作系统&#xff0c;只下载和安装实际变化的部分&#xff0c;而不是整个更新包。这样可以节省带宽和时间&#x…

LLM漫谈(二)| QAnything支持任意格式文件或数据库的本地知识库问答系统

一、QAnything介绍 QAnything (Question and Answer based on Anything) 是致力于支持任意格式文件或数据库的本地知识库问答系统&#xff0c;可断网安装使用。 您的任何格式的本地文件都可以往里扔&#xff0c;即可获得准确、快速、靠谱的问答体验。 目前已支持格式: PDF&…

Mac Parallels19.1.0 Install CentOS7.9

0、资源准备 # centos7.9镜像一份 链接: https://pan.baidu.com/s/1acIjUnsTGhk_2cYCZLSoGg?pwd6666 提取码: 6666 --来自百度网盘超级会员v7的分享1、打开PD 2、选择镜像进行安装 指定镜像名称 创建 进行密码设置 安装目的地点开后直接点击完成 网络和主机名称 开…

SonarQube 漏洞扫描

SonarQube 漏洞扫描 一、部署服务 1.1 docker方式部署 #安装docker curl -L download.beyourself.org.cn/shell-project/os/get-docker-latest.sh | sh yum install -y docker-compose #进去输入:set paste可以保证不穿行 [rootlocalhost sonar]# vim docker-compose.yml v…

什么猫粮便宜又好?什么牌子的主食冻干猫粮健康又实惠?

冻干对于猫咪的好处&#xff0c;相信许多养猫的朋友们都非常了解。冻干猫粮是将含有水分的新鲜肉在低温且真空的环境中急速冻结&#xff0c;使得冰直接升华成水蒸气&#xff0c;从而排掉水分&#xff0c;让肉变得干燥。这种方式可以保证蛋白质和维生素等物质的生物活力&#xf…

Zabbix实现网络响应超时监控

一、简介 在IT运维管理过程中&#xff0c;网络响应超时是比较常见的故障之一。尽管网络响应超时的原因多种多样&#xff0c;解决方案各不相同&#xff0c;但归根结底解决故障的首要前提是发现问题。 在网络超时监控方面&#xff0c;Zabbix能够实时捕获并响应网络设备的超时事…

技术方向:比较与选择

针对未入行、刚入行、工作好几年依然不停切换择业方向、长期技术无法突破的人。 1 技术栈 一切的开始其实是对编程的兴趣&#xff0c;兴趣指引你跨过所有障碍。 编程语言是基础&#xff0c;编程语言之上&#xff0c;发展为两个主要方向&#xff0c;服务和大数据。 2 编程语言…

【一】达梦数据库安装和使用-Windows

达梦数据库安装和使用-Windows 简介&#xff1a; 新能源行业关系到国计民生&#xff0c;保障能源安全的意识不容懈怠&#xff0c;近些年各行各业都在推进数字化进程&#xff0c;能源行业在国家3060双碳目标提出之后更是进行的如火如荼&#xff0c;能源互联网方面在数字化的同时…