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

C++构造函数调用顺序问题:对象o5为何构造1次析构3次

原因说明

你观察到的「o5只触发1次构造、却触发3次析构」是错觉:3次id=5的析构日志根本不是o5这一个对象触发的,而是3个独立、id值都为5的对象各自析构的输出。你之所以只看到1次构造日志,是因为另外两个id=5的对象是编译器通过隐式生成的拷贝构造函数创建的,你没有给拷贝构造加打印,所以看不到这两次创建过程。

3次id=5析构的对应来源

和o5相关一共存在3个独立的类实例,分别是:

  • 第一个是main函数里定义的局部对象o5:调用你写的CreateSample(int i)构造,id赋值为5,你能看到它的创建日志。main函数执行到return时o5离开作用域,触发1次id=5的析构。
  • 第二个是fuct2的形参对象:fuct2的参数是值传递void fuct2(CreateSample o),调用fuct2(o5)时,会用o5拷贝构造出一个新的临时对象作为函数形参,这个对象的id拷贝自o5,值为5。fuct2执行结束后形参离开作用域,触发1次id=5的析构。
  • 第三个是fuct2内部的局部对象o6:fuct2里的CreateSample o6 = o;是拷贝初始化语句,会用前面的形参o拷贝构造出o6,id同样为5。fuct2执行结束后o6离开作用域,触发1次id=5的析构。
验证方式

你可以给类补一个自定义的拷贝构造函数,加上创建日志,运行后就能看到完整的创建、析构对应关系:

CreateSample(const CreateSample& other)
{
    id = other.id;
    cout << "Object " << id << " is created by copy" << endl;
}

重新编译运行后,你会看到id=5的对象一共有3次创建记录(1次普通构造、2次拷贝构造),和3次析构记录完全匹配,不存在一个对象多次析构的问题。

注意:编译器隐式生成的默认拷贝构造只会做成员值的浅拷贝,不会产生任何输出,这就是你之前漏掉两次创建过程的根本原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 05:21:46