当对象释放时,避免析构函数调用两次
在上一篇文章中,我们提到过,在一个对象的析构函数中执行太多任务,可能导致对象被释放两次。解决此问题的标准方法是在析构过程中使用一个自定义的引用计数,如下图所示:
如果你有 IUnknown 接口的通用实现,则可以像我们在此处所做的那样,在 IUnknown 接口的 Release 方法中将引用计数设置为 DESTRUCTOR_REFCOUNT,并在实现的析构函数中断言该值是正确的。
由于 C++ 在派生类析构函数之后运行基类析构函数,因此基类析构函数将在派生类完成清理后检查引用计数。
通过将引用计数设置为人为的非零值,发生的任何 AddRef 和 Release 调用都不会触发重复销毁(当然,假设析构函数路径中没有人有导致它们过度释放的错误)。末尾的断言可确保在销毁过程中不会创建对对象的新引用。
这实际上更像是一种解决方法,而不是坚如磐石的解决方案,因为它假定在销毁序列期间调用的任何函数都不会保留对函数返回之外的对象的引用。这通常不是你可以假设的关于 COM 的事情。通常,方法可以自由调用 AddRef 并挂在指向对象的指针上,以便稍后完成请求的操作。
某些方法(如 IPersistPropertyBag 接口的 Load 方法) 明确禁止此类行为,但这些类型的方法更像是例外而不是规则。
课后练习题
为什么执行简单的赋值操作 m_cRef = DESTRUCTOR_REFCOUNT,而不是更复杂的互锁交换 InterlockedExchangeAdd(&m_cRef,DESTRUCTOR_REFCOUNT),这样岂不是更安全的?
总结
图中的技法,可以加以利用,以确认对象的析构函数确实仅会被释放一次。你的技能工具箱里又多了一把趁手的小玩意儿了。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。本文来自:《Avoiding double-destruction when an object is released》
上一篇:曼大历史悠久的教育领导力专业
下一篇:政法干警沉下去 矛盾化解在一线
最近更新素质教育
- 信用信息赋能,助力社会信用体系建设
- 今天距第二届全国博士后创新创业大赛总决赛还有10天!
- 北京自学考试和成教有什么不同?
- 道县:开展2023年基础教育业务工作培训
- 融入智能技术 赋能创新人才培养
- 怎么知道自己是不是脊柱侧弯?一个方法教你判断!
- 让长三角市民共享,上海城市业余联赛市面越做越大
- 华容县实验小学:最美莫过夕阳红 最浓不过敬老情
- 原创恭喜!王楚钦代替樊振东世界排名来到第一位,双方积分差仅有15分
- 自考会计专业有哪些课程?
- 播出预告丨上海市天山初级中学:不一样的学习评价
- 杭州亚残运会火炬传递圆满成功 “桂冠”画出现代版“富春山居图”
- 自考学士学位英语什么时候报名
- 日本学校要求的托福分数
- 证明差“老师”能教出好“学生”?江苏博士最新研究成果,引发国际关注!
- 让共同发展繁荣之路越走越宽广
- 原创拒绝恩比德!尼克斯目标清晰!锡伯杜点名要他,三分王成球队答案
- 喜庆乔迁五周年,共度九九重阳节
- 蚂蚁庄园今日答案最新:味精加热太久真的会致癌吗
- 2024年辽宁省普通高考报名即将开始
- 粤港澳大湾区第三届职业技能大赛将于10月23
- 难忘那次5天5夜的长途机动,还有那个同车的义务兵驾驶员
- “周五课堂”来了新老师
- 在学生中走俏的萝卜刀引发争议,消保委提醒:警惕其暴力暗示
- 校园圈丨让学生走出家门做历史作业,结果出人意料