C++矩阵运算符重载执行C=A+B时报无匹配=运算符错误
报错原因
- 核心问题是你定义的拷贝赋值运算符参数为非常量左值引用
Matrix&:C = A执行时A是已存在的左值对象,可以被该引用类型匹配,所以运行正常;而A+B的返回值是临时Matrix对象,属于右值,C++语法不允许非常量左值引用绑定到右值,因此找不到匹配的=运算符触发报错。 - 额外不符合规范的点:你声明的赋值运算符返回值为
Matrix值类型,不是你预期的对象引用,会产生多余的临时对象拷贝。同时拷贝构造函数、加减乘运算符的参数也没有加const修饰,既不符合运算符语义(运算不会修改输入参数),也无法支持传入右值参数的场景。 - 隐含问题:现有赋值运算符没有处理自赋值判断、行列数不匹配的情况,如果两个矩阵行列数不一致,直接循环赋值会发生内存越界。
修复步骤
- 修改类内的相关方法声明:
class Matrix{ private: int rows; int cols; int **ptr; public: // 拷贝构造参数加const Matrix(const Matrix &); Matrix(int, int); ~Matrix(); friend istream& operator>>(istream &, Matrix &); friend ostream& operator<<(ostream &,const Matrix &); // 输出运算符参数也加const,支持输出临时对象 // 运算符参数加const,函数本身加const表示不修改当前对象 Matrix operator +(const Matrix &) const; Matrix operator -(const Matrix &) const; Matrix operator *(const Matrix &) const; // 赋值运算符返回值改为引用,参数加const Matrix& operator =(const Matrix &); void transpose(const Matrix &); };
- 修正拷贝构造函数的参数:
Matrix::Matrix(const Matrix &m){ rows = m.rows; cols = m.cols; ptr = new int* [rows]; for(int i= 0;i<rows;i++){ ptr[i]=new int [cols]; } for(int i =0 ;i<rows;i++){ for(int j=0;j<cols;j++){ ptr[i][j] = m.ptr[i][j]; } } }
- 重写拷贝赋值运算符,新增自赋值判断和内存重新分配逻辑:
Matrix& Matrix::operator =(const Matrix & m){ // 自赋值直接返回 if(this == &m) return *this; // 释放原有内存 for(int i=0;i<rows;i++){ delete[] ptr[i]; } delete[] ptr; // 拷贝新矩阵的属性和数据 rows = m.rows; cols = m.cols; ptr = new int*[rows]; for(int i =0;i<rows;i++){ ptr[i] = new int[cols]; for(int j=0;j<cols;j++){ ptr[i][j] = m.ptr[i][j]; } } return *this; }
- 修正加减乘运算符的参数和const修饰,新增行列合法性判断:
以加法为例,其余减法、乘法同理修改:
Matrix Matrix::operator +(const Matrix &m) const{ // 提前判断行列是否匹配,避免内存越界 if(rows != m.rows || cols != m.cols){ throw "矩阵相加需要行列数完全一致"; } Matrix temp( rows, cols); for(int i =0;i<rows;i++){ for(int j=0;j<cols;j++){ temp.ptr[i][j]= ptr[i][j] + m.ptr[i][j]; } } return temp; }
完成以上修改后,C = A + B就可以正常运行了。另外建议在main函数中执行矩阵运算前先判断两个矩阵的行列是否符合运算要求,避免运行时报错。
内容的提问来源于stack exchange,提问作者vivek uniyal
相关产品推荐
相关产品推荐

