C++运算符重载问题:析构函数异常调用疑惑
问题分析与解决:运算符重载后析构函数被调用的原因
你看到析构函数被调用的直接原因是**operator+返回了局部对象的引用**:
在operator+函数里创建的newTest是局部变量,当函数执行完毕退出时,局部对象会被自动销毁,此时就会触发析构函数。
更严重的是,这个写法会导致悬垂引用:你返回的引用指向已经被销毁的对象,test2 num3 = num2 + 2;这行代码尝试用这个无效的引用来初始化num3,属于C++里的未定义行为,后续使用num3大概率会导致程序崩溃或出现异常结果。
正确的写法修正
加法运算符的语义是生成一个新对象,而不是修改原对象,所以operator+应该返回对象本身,而不是引用。另外你的代码还有其他几个必须修复的问题:
- 缺少匹配的构造函数:main里尝试用数组和大小初始化对象,但类里没有对应的构造函数
- 缺少拷贝构造函数和赋值运算符:类内有动态分配的内存,默认浅拷贝会导致重复释放内存的错误
- 默认构造函数设为private,会限制一些合法操作
修正后的代码示例:
#include <iostream> class test2 { private: double* array; int size; public: // 默认构造函数 test2() : array(nullptr), size(0) {} // 接受大小的构造函数 test2(int n) : size(n) { array = new double[size]; for (int i = 0; i < size; i++) { array[i] = 0; } } // 接受数组和大小的构造函数 test2(double arr[], int n) : size(n) { array = new double[size]; for (int i = 0; i < size; i++) { array[i] = arr[i]; } } // 拷贝构造函数(深拷贝) test2(const test2& other) { size = other.size; array = new double[size]; for (int i = 0; i < size; i++) { array[i] = other.array[i]; } } // 赋值运算符重载(深拷贝) test2& operator=(const test2& other) { if (this != &other) { // 防止自赋值 delete[] array; // 释放当前对象的内存 size = other.size; array = new double[size]; for (int i = 0; i < size; i++) { array[i] = other.array[i]; } } return *this; } double& operator[](int index) { return array[index]; } // operator+返回对象,而非引用 test2 operator+(double d) const { // 加const表示不修改原对象 test2 newTest(size); for (int i = 0; i < size; i++) { newTest[i] = array[i] + d; } return newTest; } ~test2() { delete[] array; } }; int main() { double array[] = { 1.1, 1.2, 1.3}; test2 num2(array, 3); test2 num3 = num2 + 2; return 0; }
关键说明
operator+改为返回test2对象:这样函数返回时会调用拷贝构造函数(或移动构造,C++11及以后)创建临时对象,用来初始化num3,局部对象newTest销毁时的析构是正常的,但不会影响后续的num3。- 添加深拷贝的拷贝构造和赋值运算符:确保每个对象拥有独立的内存空间,避免析构时重复释放同一块内存。
- 补全必要的构造函数:匹配main里的初始化需求。
内容的提问来源于stack exchange,提问作者Festik
相关产品推荐
相关产品推荐

