C++如何将对象存入数组,避免对象被立即析构?
问题原因
你观察到的立即析构的是赋值语句右侧的临时对象,并非数组内存储的对象,完整执行逻辑如下:
- 运行
Thing arr[1];时,数组会默认构造1个Thing实例,该实例生命周期和数组绑定,会持续到main函数执行结束 - 运行
arr[0] = Thing();时,右侧Thing()会生成一个临时对象,编译器自动调用默认生成的拷贝赋值运算符,将临时对象的内容浅拷贝给数组中已存在的arr[0]实例 - 赋值语句执行完毕后,临时对象生命周期终止,立刻触发析构函数输出打印内容,这就是你看到的“对象被立即析构”的来源
- 数组内的
arr[0]实例会在你完成x的输入、main函数即将退出时才会析构。你目前没有看到这部分析构输出,一是因为程序阻塞在cin读取步骤,未走到main结束阶段;二是析构函数的打印没有加换行符,两次析构的输出会粘连在一起,不易区分。
验证方法
修改代码增加对象标识和换行,就能清晰区分两次析构调用:
#include <iostream> class Thing{ public: int id; Thing(int id = 0):id(id){} ~Thing(){ std::cout<<"Thing "<<id<<" destructing\n"; } }; int main(){ Thing arr[1] = {1}; // 数组内初始对象id为1 arr[0] = Thing(2); // 临时对象id为2 int x; std::cin>>x; }
运行后会先打印Thing 2 destructing,这是临时对象析构;输入任意内容让程序退出时,会再打印Thing 2 destructing,这是数组内存储的对象析构(赋值操作已经把数组内对象的id覆盖为2)。
优化建议
如果要避免额外的临时对象创建和析构,可以直接在数组初始化阶段构造目标对象,不需要后续赋值:
int main(){ Thing arr[1] = {Thing()}; // 编译器会做复制消除,不会产生额外临时对象 int x; std::cin>>x; }
内容的提问来源于stack exchange,提问作者Kay.Z
相关产品推荐
相关产品推荐

