You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在成员函数内销毁this指向对象再重建是否属于定义行为?

在C++成员函数中先销毁自身再原地重建对象是否是定义行为?

先直接给结论:这段代码的行为是定义良好的,属于C++标准明确允许的操作。下面我一步步拆解为什么它合法:

首先聚焦代码里的核心操作:在do_smth()成员函数中,先通过this->~foo()显式调用当前对象的析构函数,再用placement new在this指向的内存位置重新构造一个foo对象。我们逐个环节分析合法性:

  • 显式析构的合理性:对于main里这种自动存储期的对象f,显式调用析构函数是允许的——这只会结束对象的生命周期,但不会释放它占据的内存(自动变量的内存会在作用域结束时由编译器自动回收)。不过要注意:析构后如果不重新构造,再访问原对象的任何成员都是未定义行为,而你的代码紧接着就做了重建,避开了这个坑。

  • placement new的合法性:this指向的内存区域仍然有效(因为f的作用域还没结束,内存没被回收),而且这块区域的大小、对齐方式完全匹配foo类型的要求(毕竟原本就是用来存foo对象的),所以在这里用placement new构造新的foo对象完全符合标准。

  • 重建后对象的访问合法性:当我们在原对象的存储位置上构造了同类型(忽略cv限定)的新对象后,原来的变量名f会自动绑定到这个新对象上。所以main里调用f.print()时,访问的是重建后的新对象的x成员,这是完全合法的。

当然,这种操作也有一些需要警惕的边界情况:

  • 如果原对象是const限定的,或者包含引用成员、const成员,这种原地销毁重建的操作可能会触发未定义行为;
  • 析构完成后到重建完成前的这段时间,绝对不能访问this指向的任何成员,否则也是未定义行为。

但回到你给出的代码,这些问题都不存在,所以整个行为是完全符合标准的定义行为。

内容的提问来源于stack exchange,提问作者Incomputable

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:57:41