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

引子:今天在看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.mzph.cn/news/604741.shtml

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

相关文章

MySQL忘记密码,如何重置密码(Windows)

1. 停止MySQL服务 打开“服务”管理工具&#xff08;可以在开始菜单搜索“服务”或运行 services.msc&#xff09;。 找到你的MySQL服务&#xff0c;可能叫别的&#xff0c;但是应该都是mysql开头的。 鼠标右键停止运行它。 2. 跳过权限表启动 MySQL 打开命令提示符&#x…

HTML5 新元素

新多媒体元素 标签描述<audio>定义音频内容<video>定义视频&#xff08;video 或者 movie&#xff09;<source>定义多媒体资源 <video> 和 <audio><embed>定义嵌入的内容&#xff0c;比如插件。<track>为诸如 <video> 和 <…

理论U2 贝叶斯决策理论

文章目录 一、概率统计理论基础1、乘法公式2、全概率公式3、贝叶斯公式 二、贝叶斯决策理论1、用处2、解决问题3、决策基础4、一些概念5、核心公式 三、最小错误率贝叶斯决策1、目标2、例题分析3、问题1&#xff09;决策的风险 四、最小风险贝叶斯决策1、背景2、基本概念1&…

西电期末1034.勒让德多项式

一.题目 二.分析与思路 带递推式即可&#xff0c;注意数据类型的使用和转换&#xff01; 三.代码实现 #include<bits/stdc.h>//万能头 int main() {int n;double x;scanf("%d%lf",&n,&x);double ans0;double num[n];num[0]1;num[1]x;//初始化ansnum…

VS2017 CMake编译Opencv

先下载opencv4.2.0源码以及opencv_contrib-4.2.0 地址链接&#xff1a;https://pan.baidu.com/s/1AgFsiH4uMqTRJftNXAqmTw?pwd3663 提取码&#xff1a;3663 先建立一个opencv_debug和opencv_release文件夹这两个都是为了后续存放编译好的debug版本和release版本opencv的&#…

jaeger简单发送---链路追踪

jaeger go发送单个span package mainimport ("fmt""github.com/uber/jaeger-client-go"jaegercfg "github.com/uber/jaeger-client-go/config" )func main() {cfg : jaegercfg.Configuration{Sampler: &jaegercfg.SamplerConfig{ //采样类…

小程序 蓝牙连接与回连过程

小程序蓝牙连接过程包括扫描设备、连接设备和发送数据等步骤 具体步骤如下&#xff1a; 打开蓝牙&#xff1a;在小程序中调用wx.openBluetoothAdapter()函数打开蓝牙适配器。 监听蓝牙适配器状态&#xff1a;使用wx.onBluetoothAdapterStateChange()函数监听蓝牙适配器的状态…

2023年12 月电子学会Python等级考试试卷(一级)答案解析

青少年软件编程(Python)等级考试试卷(一级) 分数:100 题数:37 一、单选题(共25题,共50分) 1. 下列程序运行的结果是?( ) print(hello) print(world) A. helloworld

部署可道云网盘的一个漏洞解决

目录 1漏洞展示 2.防范措施 1漏洞展示 因为可道云网盘的上传文档有保存在 /data/Group/public/home/文档/ 中,当别有用心之人知道个人部署的域名与上次的文件后&#xff0c;可以进行访问拿到uid。例我在我部署的网盘上上次一个aa.php 文件&#xff0c;然后拿来演示 然后通过…

LeetCode刷题笔记之栈与队列

一、队列与栈相互转换 1. 232【用栈实现队列】 题目&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末…

Java SE入门及基础(5)

变量的定义与使用 1. 变量的概念 从字面意思看&#xff0c;变量就是会变化的量。 从计算机专业角度看&#xff0c;变量就是一个内存空间地址的表示。 在Java中&#xff0c;内存分为栈内存和堆内存两大块 2. 变量的声明 语法 数据类型 变量名 ; 变量名 变量值…

Python笔记07-异常、模块和包

文章目录 异常及捕获方法python模块python包安装第三方包 异常及捕获方法 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”, 也就是我们常说的BUG 例如&#xff1a;以r方式打开一个不存在的…

LNMP架构及应用部署

目录 简介 1、构建LNMP网站平台 1.1、安装MySQL数据库 &#xff08;1&#xff09;编译安装MySQL &#xff08;2&#xff09;优化调整 &#xff08;3&#xff09;初始化数据库 &#xff08;4&#xff09;启动mysql服务 1.2、安装PHP解析环境 &#xff08;1&#xf…

【pytorch学习】 深度学习 教程 and 实战

pytorch编程实战博主&#xff1a;https://github.com/lucidrains https://github.com/lucidrains/vit-pytorch

K8S-环境部署

1 基础环境配置 主机名规划 序号主机ip主机名规划110.0.0.12kubernetes-master.sswang.com kubernetes-master210.0.0.15kubernetes-node1.sswang.com kubernetes-node1310.0.0.16kubernetes-node2.sswang.com kubernetes-node2410.0.0.17kubernetes-node3.sswang.com kubern…

【Java】设计模式之两阶段终止

两阶段终止 两阶段终止&#xff0c;即Two Phase Termination。是用来终止线程的套路。 它的思想是&#xff0c;如何在一个线程T1中优雅地终止线程T2&#xff1f;这里的【优雅】指的是给T2一个料理后事的机会。 错误思路&#xff1a; 使用stop方法。stop 方法会真正杀死线程…

uniapp上传文件时用到的api是什么?格式是什么?

在UniApp中&#xff0c;你可以使用uni.uploadFile()方法来上传文件。这是一个异步方法&#xff0c;用于将本地资源上传到服务器。 该方法的基本格式如下&#xff1a; uni.uploadFile({url: 上传接口地址,filePath: 要上传的文件路径,name: 后端接收的文件参数名,formData: {/…

58. 最后一个单词的长度(Java)

题目描述 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 输入&#xff1a; s “luffy is still joyboy” 输出&#xff1a; 6 解释&am…

[足式机器人]Part3 机构运动学与动力学分析与建模 Ch00-1 坐标系与概念基准

本文仅供学习使用&#xff0c;总结很多本现有讲述运动学或动力学书籍后的总结&#xff0c;从矢量的角度进行分析&#xff0c;方法比较传统&#xff0c;但更易理解&#xff0c;并且现有的看似抽象方法&#xff0c;两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有…

“华为杯“第十三届中国研究生数学建模竞赛-A题:关于跳台跳水体型系数设置的建模分析(续)

目录 5.4.1 问题分析与建模 5.4.2 计算与求解 5.5 结论 5.5.2 当空中存在两个动作时