L.Maple
L.Maple

Reputation: 141

C++ the operator overloading

I do not know why the error after the definition of the operator overload function.the error is : no match for 'operator=' (operand types are 'Matrix' and 'Matrix'),a1+a4 after operator + overload function is only one matrix object that returns.so here should be a1 = object matrix?

#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;
}

Upvotes: 1

Views: 208

Answers (2)

AliciaBytes
AliciaBytes

Reputation: 7439

Your problem stems from a combination of 2 things. Let's first look at the line the error occurs:

a3 = (a1+a4);

So it tries to assign the result of an addition. Let's look at the declaration for the operator+:

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

You return a new Matrix object per value. That's the right thing to do but ends up biting us due to how your operator= is incorrectly declared:

Matrix& operator = (Matrix &b);

The problem is with the argument type Matrix &. Since we return per value from the operator+ we end up with a temporary object. But binding a non-const reference to a temporary isn't allowed, and in fact it doesn't make sense to change temporaries through a non-const reference since they'll just be discared anyways.

change both the declaration and definition to:

Matrix& operator = (const Matrix &b);

and it should work, it also makes sense as you never want to accidentally change the right hand side of an assignment.


Update to follow up question in comment:

I'd suggest using

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

That is take the arguments as const references but keep the returned value as non-const.

  1. The reason to take the arguments as const references is that it can help prevent errors and you want to make use of it as much as you can. For example if you accidentally wrote if (a = b) instead of if (a ==b) in a function that isn't supposed to modify the values, you'd get a nice error with const. Without const you'd have to search around looking where you accidentally changed the value.

  2. The reason to return as non-const is to make use of move semantics which only work if you return a value as non-const and could be an optimization here. Also the temporary returned isn't const it just doesn't make sense to bind it to a non-const reference from the languages point of view.

Upvotes: 1

James Adkison
James Adkison

Reputation: 9602

The problem is that your assignment operator currently takes a non-const Matrix reference. However, (a1+a4) generates a temporary object which cannot be bound to a non-const reference. See the following fixes to get your code compiling.

#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;
}

Live example

Note: The getArr function had to be made const correct so that it could be called by the const Matrix& parameter in the assignment operator.

Upvotes: 2

Related Questions