如何解决访问用户定义的析构函数已启动但未完成的对象真的是UB吗?
问题是由 a discussion on Reddit 引起的,一位用户告诉我,引用了标准关于对象生命周期的规则:
我很确定在对象被破坏时访问对象在技术上是 UB。
例如,我依赖于管理后台线程的类;我让他们的析构函数通知线程退出并等待它退出,并且该线程可以访问该对象。我需要重构我的代码吗?
解决方法
不,它定义明确。
如果 UB 在其析构函数执行时访问该对象,则该析构函数本身将无法对自己的对象执行任何操作。 ?
在您的析构函数执行期间:
- 基地尚未被摧毁
- “当前”对象本身还没有被破坏(也没有它的成员)
- 一些资源可能已经被释放,如果你已经在析构函数中释放了
- 派生的子对象已被破坏
- 虚拟函数调用将安全地引用“当前”对象,而不是这些现已失效的派生子对象
-
dynamic_cast
和typeid
会做同样的事情 - 但是,您不能使用
Derived*
执行任何这些操作!通过Base*
或Current*
很好
这些规则中的大部分都包含在 [class.cdtor]
中。
虽然对象的生命周期确实在技术上以析构函数“调用”的开始结束,但此时您处于一种炼狱中,其中 [class.cdtor]
接管列出的规则以上:
[basic.life/7]
:[..] 在一个对象的生命周期结束之后,在该对象占用的存储空间被重用或释放之前,任何引用原始对象的泛左值都可以可以使用,但只能以有限的方式使用。对于正在构建或销毁的对象,请参阅 [class.cdtor]。 [..]
这可能是一种容易出错且令人困惑的模式,但它本质上并非不正确。对于您的特定用例,我什至将其称为合理的常规。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。