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

C++中类及成员析构函数被调用两次的原因咨询

为什么手动调用析构函数后会出现重复的销毁输出?

先看你的代码:

class A { public: ~A() { std::cout << "A destroyed" << std::endl; } }; 
class B { public: A a; ~B() { std::cout << "B destroyed" << std::endl; } }; 
int main() { B b; b.~B(); }

你预期只输出一次 B destroyed A destroyed,但实际输出是:

B destroyed
A destroyed
B destroyed
A destroyed

核心问题:手动调用析构函数≠销毁对象

在C++里,手动调用析构函数(比如b.~B())仅仅是执行析构函数内的代码逻辑,并不会真正销毁对象、释放其占用的内存,也不会把对象标记为已死亡。

具体到你的代码流程:

  1. 手动调用b.~B()时:

    • 先执行B的析构函数体,输出B destroyed
    • 由于B包含成员对象A a,C++会自动触发a的析构函数,输出A destroyed
      但此时b作为栈上的局部变量,其内存空间依然存在,对象并没有被真正“移除”。
  2. 当main函数执行完毕时,栈上的局部变量会被自动清理:

    • 系统会再次调用B的析构函数,输出B destroyed
    • 同样,再次自动调用成员a的析构函数,输出A destroyed

这就造成了两次完整的销毁输出。

重要提醒

手动调用析构函数几乎只有在配合placement new(在预先分配的内存上构造对象)时才是合理的操作。对于普通的栈对象或new出来的堆对象,完全不需要手动调用析构函数——系统会自动处理对象的生命周期,手动调用只会导致析构逻辑重复执行,甚至引发未定义行为(比如析构函数里有资源释放操作的话,重复执行会导致二次释放)。

内容的提问来源于stack exchange,提问作者Jamāl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:24:04