如何在循环中延迟C++类的析构函数调用?
延迟C++对象析构时机的解决方案
原代码
// 在线C++编译器运行代码 #include <iostream> #include <iterator> #include <set> int index; int member[5] = {0,1,2,3,4}; class Animal{ public: Animal(int val){ member[val]=-1; } ~Animal(){ member[index]=index; } }; int main() { // 编写C++代码 for(int i=0;i<5;i++){ std::cout<<member[i]<<" "; } std::cout<<std::endl; for(int i=0;i<5;i++){ index=i; Animal a(i); } for(int i=0;i<5;i++){ std::cout<<member[i]<<" "; } return 0; }
当前输出
0 1 2 3 4
0 1 2 3 4
期望输出
0 1 2 3 4
-1 -1 -1 -1 -1
问题原因
循环内创建的Animal是局部变量,每次迭代结束后会立即被析构。构造函数刚把member[val]设为-1,析构函数就将member[index]恢复为index值,导致数组回到初始状态。此外原代码存在隐藏问题:全局变量index在所有对象析构时的值是循环最后一次的4,会导致只有member[4]被重复恢复,其他位置无法正确还原。
解决方案
核心是让Animal对象拥有main函数级别的生命周期,同时修正析构函数逻辑,使其能正确恢复对应位置的值。
方案1:用std::vector存储对象(推荐)
通过容器存储Animal实例,容器生命周期与main函数一致,内部对象会在main结束时才被析构。同时给Animal类添加成员变量记录自身对应的索引,避免依赖全局变量。
修改后代码:
// 在线C++编译器运行代码 #include <iostream> #include <vector> int member[5] = {0,1,2,3,4}; class Animal{ public: Animal(int val) : _val(val) { member[val] = -1; } ~Animal(){ member[_val] = _val; } private: int _val; // 记录当前对象对应的索引,避免依赖全局变量 }; int main() { // 输出初始数组 for(int i=0;i<5;i++){ std::cout << member[i] << " "; } std::cout << std::endl; std::vector<Animal> animals; for(int i=0;i<5;i++){ animals.emplace_back(i); // 在容器内直接构造对象 } // 输出修改后的数组 for(int i=0;i<5;i++){ std::cout << member[i] << " "; } std::cout << std::endl; return 0; }
方案2:动态分配对象(需手动管理内存)
用new创建对象,将指针存入数组,在main末尾统一delete触发析构。这种方式需要手动管理内存,容易出现泄漏,不推荐。
示例代码:
// 在线C++编译器运行代码 #include <iostream> int member[5] = {0,1,2,3,4}; class Animal{ public: int _val; Animal(int val) : _val(val) { member[val] = -1; } ~Animal(){ member[_val] = _val; } }; int main() { // 输出初始数组 for(int i=0;i<5;i++){ std::cout << member[i] << " "; } std::cout << std::endl; Animal* animals[5]; for(int i=0;i<5;i++){ animals[i] = new Animal(i); } // 输出修改后的数组 for(int i=0;i<5;i++){ std::cout << member[i] << " "; } std::cout << std::endl; // 手动触发析构 for(int i=0;i<5;i++){ delete animals[i]; } return 0; }
内容的提问来源于stack exchange,提问作者Vasu Gupta
相关产品推荐
相关产品推荐

