为何自定义Array类的加法运算符无法返回正确数组?
问题排查:Array类加法运算符无法正确返回求和数组
你的代码中加法运算符逻辑看似正确,但返回的数组会出现错误值,核心原因是Array类缺少深拷贝的拷贝构造函数和赋值运算符,导致浅拷贝引发的悬空指针问题:
问题根源
编译器会为类自动生成默认的拷贝构造函数和赋值运算符,但它们只会做浅拷贝——仅复制size和arr指针的值,而不会重新分配内存复制数组元素。当operator+函数结束时,局部对象tempArr被析构,delete[] arr释放了内存,返回的对象里的arr指针就指向了已被释放的内存,后续调用showArr时访问的是无效内存,结果自然错误。
修复步骤
1. 添加拷贝构造函数(深拷贝)
在Array类的public区域添加:
Array(const Array& other) { size = other.size; arr = new int[size]; // 复制每个元素 for (int i = 0; i < size; ++i) { arr[i] = other.arr[i]; } }
2. 添加赋值运算符重载(深拷贝)
同样在public区域添加:
Array& operator=(const Array& other) { if (this != &other) { // 防止自赋值导致内存泄漏 delete[] arr; // 释放当前对象的旧内存 size = other.size; arr = new int[size]; for (int i = 0; i < size; ++i) { arr[i] = other.arr[i]; } } return *this; }
3. 优化运算符参数与成员函数
- 将
operator+和operator*的参数改为const引用,避免不必要的拷贝:Array operator + (const Array& arr1, const Array& arr2) { int temp = std::min(arr1.getSize(), arr2.getSize()); Array tempArr(temp); for (size_t i = 0; i < temp; ++i) { tempArr[i] = arr1[i] + arr2[i]; } return tempArr; } Array operator * (const Array& arr1, const Array& arr2) { int temp = std::min(arr1.getSize(), arr2.getSize()); Array tempArr(temp); for (size_t i = 0; i < temp; ++i) { tempArr[i] = arr1[i] * arr2[i]; } return tempArr; } - 将
getSize()和operator[]修改为const成员函数(同时保留非const版本支持修改):int getSize() const { return size; } // const版本,供const对象调用 const int& operator [] (const int index) const { return arr[index]; } // 非const版本,供普通对象调用 int& operator [] (const int index) { return arr[index]; }
修复后完整代码
#include <iostream> #include <algorithm> // 用于std::min void showMenu() { std::cout << "-------Menu-------" << std::endl << "1-Input matrix" << std::endl << "2-Print matrix" << std::endl << "3-Sum matrix" << std::endl << "4-Multiply matrix" << std::endl << "0-Exit" << std::endl << "------------------" << std::endl; } class Array { public: Array(const int size) { this->size = size; arr = new int[this->size]; } // 拷贝构造函数 Array(const Array& other) { size = other.size; arr = new int[size]; for (int i = 0; i < size; ++i) { arr[i] = other.arr[i]; } } // 赋值运算符重载 Array& operator=(const Array& other) { if (this != &other) { delete[] arr; size = other.size; arr = new int[size]; for (int i = 0; i < size; ++i) { arr[i] = other.arr[i]; } } return *this; } void fillArr() { std::cout << "Enter elements of array: "; for (size_t i = 0; i < size; i++) { std::cin >> arr[i]; } } int getSize() const { return size; } const int& operator [] (const int index) const { return arr[index]; } int& operator [] (const int index) { return arr[index]; } void showArr() { for (size_t i = 0; i < size; i++) { std::cout << arr[i] << '\t'; } std::cout << std::endl; } ~Array() { delete[] arr; } private: int size = 0; int* arr; }; Array operator + (const Array& arr1, const Array& arr2) { int temp = std::min(arr1.getSize(), arr2.getSize()); Array tempArr(temp); for (size_t i = 0; i < temp; ++i) { tempArr[i] = arr1[i] + arr2[i]; } return tempArr; } Array operator * (const Array& arr1, const Array& arr2) { int temp = std::min(arr1.getSize(), arr2.getSize()); Array tempArr(temp); for (size_t i = 0; i < temp; ++i) { tempArr[i] = arr1[i] * arr2[i]; } return tempArr; } int main() { int num = 0; int size1 = 0, size2 = 0; std::cout << "Enter size of first array: "; std::cin >> size1; std::cout << "Enter size of second array: "; std::cin >> size2; Array arr1(size1), arr2(size2); while (true) { showMenu(); std::cout << "Choice: "; std::cin >> num; switch (num) { case 1: arr1.fillArr(); arr2.fillArr(); break; case 2: arr1.showArr(); arr2.showArr(); break; case 3: { Array temp(arr1 + arr2); temp.showArr(); break; } case 4: (arr1 * arr2).showArr(); break; case 0: return 0; // 添加退出逻辑 default: std::cout << "Invalid choice, try again." << std::endl; } } }
补充说明:原代码main函数未处理退出逻辑,修复后添加了case 0的返回语句,避免无限循环。
内容的提问来源于stack exchange,提问作者Blinovich
相关产品推荐
相关产品推荐

