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
相关产品推荐
相关产品推荐

