shared_ptr or weak_ptr

本文探讨了如何根据对象的可用状态选择使用shared_ptr还是weak_ptr,包括对象的生命/对象的存在的概念、多客户端共享对象时的可用状态、以及不同场景下对象可用性的决定权。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文讨论的焦点是一个对象的“可用状态”,从设计的角度看如何使用shared_ptr还是weak_ptr来考虑这个问题

这里所说的“对象可用”是指调用这个对象时是,安全的,数据是正确的,执行时能够实现对应的功能

而“对象不可用””是指调用这个对象时是,不安全的,不能保证数据的正确性,不能保证能够实现对应的功能


我们可以用“对象的生命/对象的是否存在(还活在内存中)”来表示对象的“可用状态”;当然我们可能也可以用其他方式来表示它的“可用状态”(后面有例子)

很多时候,我们可以选择用“对象的生命/对象的是否存在”来表示对象的“可用状态”, 因为这样的做法很多时候简单合理(尤其是函数指针时);

而且,“对象的生命/对象的是否存在”也是“对象可用状态”的必要非充分条件,

因为当对象不存在时,它也肯定就不可用了;这里“不可用”是指不能调用这个对象的属性或方法

而当对象仍存在时,依据设计,可能它早已不可用;这里“不可用”是指,如果仍去调用这个对象的属性或方法,不能完成原有功能,不能保证安全


如果我们选择用“对象的生命/对象的是否存在”来表示对象的“可用状态”

那么“对象的生命/对象的是否存在”就等价于它的“可用状态”,这时我们就应该慎用shared_ptr


当多个client使用shared_ptr来共享了一个对象时,“对象的生命/对象的是否存在”就被这些client平等地共享了

比如clientA, clientB使用一个相同的shared_ptr<Object> p

当clientA释放了p,而clientB没有释放p,p所指的对象不会被释放,这个对象还活着还存在 --> 那么就说明了这个对象还“可用”

也就是说,clientA和clientB共同决定了p所指的对象的可用状态,当任一个client不删它它就仍然可用


但是有时,从需求来说,并不是想让clientA和clientB共同来决定p所指的对象是否可用

有时只想让clientA来决定p所指的对象的可用状态,

而只有当p所指的对象仍然可用(仍然活着)时clientB才去使用这个对象,不希望clientB来决定p所指对象的可用状态

这时clientB就不应该使用shared_ptr,clientB用weak_ptr更合适

因为clientB需要的是一个“观察者”,clientB不应该享有“决定这个对象生命/可用状态的权利”


任何涉及“可用状态”的对象,当选择用“对象的生命/对象的是否存在”来表示对象的“可用状态”时,都应该仔细考虑这个问题

这里的p可以是函数对象,也可以是指向clientA,等等


如果涉及了多个对象,比如clientB使用functorA的一个函数对象,函数的参数又指向其他几个对象paramC,paramD,函数内部又使用其他函数对象functorE

那么每个使用对象的地方都应该考虑对象可用状态的问题

所以,clientB应该想到functorA和paramC,paramD的可用状态;functorA应该考虑到paramC,paramD和functorE的可用状态


===========================================================================================================


当然我们可能也可以用其他方式来表示它的“可用状态”,下面只是一种小例子

比如clientA可以调用clientB.subscribe(XXX, p)来把p传给clientB,XXX表示一个想订阅的东东

当clientA不再需要订阅时,再调用clientB.unsubscribe(XXX)

这时可以设计让clientB 默认unsubscribe后,p就不再可用了



资源下载链接为: https://pan.quark.cn/s/9648a1f24758 这个HTML文件是一个专门设计的网页,适合在告白或纪念日这样的特殊时刻送给女朋友,给她带来惊喜。它通过HTML技术,将普通文字转化为富有情感和创意的表达方式,让数字媒体也能传递深情。HTML(HyperText Markup Language)是构建网页的基础语言,通过标签描述网页结构和内容,让浏览器正确展示页面。在这个特效网页中,开发者可能使用了HTML5的新特性,比如音频、视频、Canvas画布或WebGL图形,来提升视觉效果和交互体验。 原本这个文件可能是基于ASP.NET技术构建的,其扩展名是“.aspx”。ASP.NET是微软开发的一个服务器端Web应用程序框架,支持多种编程语言(如C#或VB.NET)来编写动态网页。但为了在本地直接运行,不依赖服务器,开发者将其转换为纯静态的HTML格式,只需浏览器即可打开查看。 在使用这个HTML特效页时,建议使用Internet Explorer(IE)浏览器,因为一些老的或特定的网页特效可能只在IE上表现正常,尤其是那些依赖ActiveX控件或IE特有功能的页面。不过,由于IE逐渐被淘汰,现代网页可能不再对其进行优化,因此在其他现代浏览器上运行可能会出现问题。 压缩包内的文件“yangyisen0713-7561403-biaobai(html版本)_1598430618”是经过压缩的HTML文件,可能包含图片、CSS样式表和JavaScript脚本等资源。用户需要先解压,然后在浏览器中打开HTML文件,就能看到预设的告白或纪念日特效。 这个项目展示了HTML作为动态和互动内容载体的强大能力,也提醒我们,尽管技术在进步,但有时复古的方式(如使用IE浏览器)仍能唤起怀旧之情。在准备类似的个性化礼物时,掌握基本的HTML和网页制作技巧非常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值