C++运算符重载

C++ the operator overloading

本文关键字:重载 运算符 C++      更新时间:2023-10-16

我不知道为什么定义运算符重载函数后会出现错误。错误是:"operator="(操作数类型为"Matrix"answers"Matrix")不匹配,运算符+重载函数后的a1+a4只是一个返回的矩阵对象。所以这里应该是a1=对象矩阵吗?

#include<iostream>
using namespace std;
//write your code here
class Matrix{
  private:
    int arr[3][3];
  public:
    friend istream& operator >> (istream& in,Matrix &matrix);
    friend ostream& operator << (ostream& out,const Matrix& matrix);
    friend Matrix operator + (Matrix &a,Matrix &b);
    void setArr(int i,int j,int data){
        arr[i][j] = data;
    }
    int getArr(int i,int j){
        return arr[i][j];
    }
    Matrix& operator = (Matrix &b);
};
istream& operator >> (istream& in,Matrix &matrix)
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            in >> matrix.arr[i][j];
    return in;
}
ostream& operator << (ostream& out,const Matrix &matrix){
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
            out << matrix.arr[i][j] << " ";
        out << endl;
    }       
    return out;
}
Matrix operator + (Matrix &a,Matrix &b){
    Matrix temp;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            temp.setArr(i,j,(a.getArr(i,j)+b.getArr(i,j)));
    return temp;
}
Matrix& Matrix::operator = (Matrix &b){
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            arr[i][j] = b.getArr(i,j);
    return *this;
}
int main()
{
    Matrix a1,a2,a3,a4;
    cin >> a1;
    cin >> a2;
    a4 = a2;
    a3 = (a1+a4); //an error over there
    cout << a1 << endl;
    cout << a2 << endl;
    cout << a3 << endl;
    return 0;
}

问题是您的赋值运算符当前采用const Matrix引用。但是,(a1+a4)生成一个临时对象,该对象不能绑定到-const引用。请参阅以下修复程序以编译代码。

#include<iostream>
using namespace std;
//write your code here
class Matrix{
  private:
    int arr[3][3];
  public:
    friend istream& operator >> (istream& in,Matrix &matrix);
    friend ostream& operator << (ostream& out,const Matrix& matrix);
    friend Matrix operator + (Matrix &a,Matrix &b);
    void setArr(int i,int j,int data){
        arr[i][j] = data;
    }
    int getArr(int i,int j) const{
    //                      ^^^^^ // Added const
        return arr[i][j];
    }
    Matrix& operator = (const Matrix &b);
    //                  ^^^^^ // Added const
};
istream& operator >> (istream& in,Matrix &matrix)
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            in >> matrix.arr[i][j];
    return in;
}
ostream& operator << (ostream& out,const Matrix &matrix){
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
            out << matrix.arr[i][j] << " ";
        out << endl;
    }       
    return out;
}
Matrix operator + (Matrix &a,Matrix &b){
    Matrix temp;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            temp.setArr(i,j,(a.getArr(i,j)+b.getArr(i,j)));
    return temp;
}
Matrix& Matrix::operator = (const Matrix &b){
//                          ^^^^^ // Added const
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            arr[i][j] = b.getArr(i,j);
    return *this;
}
int main()
{
    Matrix a1,a2,a3,a4;
    cin >> a1;
    cin >> a2;
    a4 = a2;
    a3 = (a1+a4); // No errors now
    cout << a1 << endl;
    cout << a2 << endl;
    cout << a3 << endl;
    return 0;
}

实例

注意:必须使getArr函数常量正确,以便它可以由赋值运算符中的const Matrix&参数调用。

您的问题源于两件事的组合。让我们先来看看发生错误的那一行:

a3 = (a1+a4);

因此,它试图分配加法的结果。让我们看看operator+:的声明

friend Matrix operator + (Matrix &a,Matrix &b);

每个值返回一个新的Matrix对象。这是正确的做法,但最终会因为您的operator=声明错误而刺痛我们:

Matrix& operator = (Matrix &b);

问题出在参数类型Matrix &上。由于我们从operator+返回per值,因此我们最终得到一个临时对象。但是,不允许将非常量引用绑定到临时引用,事实上,通过非常量引用更改临时引用是没有意义的,因为它们无论如何都会被讨论。

将声明和定义更改为:

Matrix& operator = (const Matrix &b);

它应该起作用,它也很有意义,因为你永远不想意外地更改任务的右侧。


更新以跟进评论中的问题:

我建议使用

friend Matrix operator +(const Matrix &a,const Matrix &b);

也就是说,将参数作为const引用,但将返回值保持为非常量

  1. 将参数作为const引用的原因是它可以帮助防止错误,并且您希望尽可能多地使用它。例如,如果您不小心在一个不应该修改值的函数中写入了if (a = b)而不是if (a ==b),那么const会出现一个很好的错误。如果没有const,您将不得不四处搜索,查找意外更改值的位置。

  2. 返回为非常量的原因是使用移动语义,只有当您返回值为non-const时,移动语义才有效,并且可能是此处的优化。此外,临时返回的不是const,只是从语言的角度来看,将其绑定到非常量引用是没有意义的。