-1

I am writing a program for Matrix operation using operator overloading but getting an error for "=" operator overloading Here's the full code. I have also returned my reference object by using (return *this) in " = " operator declaration but don't know why it is not Working . When i am using C = A it's not showing any errors but when i am using C = A + B then this error is coming up

#include<iostream>
#include<iomanip>
#include<string.h>

using namespace std;

class Matrix{
    private:
        int rows;   //For rows
        int cols;   //For columns
        int **ptr; //pointer to pointer to point in the array 
    public:
    //Declaring Constructors and destructors
        Matrix(Matrix &);
        Matrix(int, int);
        ~Matrix();
    //Declaring other functions
        friend istream& operator>>(istream &, Matrix &);
        friend ostream& operator<<(ostream &,Matrix &);
        Matrix operator +(Matrix &);
        Matrix operator -(Matrix &);
        Matrix operator *(Matrix &);
        Matrix operator =(Matrix &);
        void transpose(Matrix &);
    //End of class definition
};

//Defining Copy constructor
Matrix::Matrix(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];
         }
     }
}

//Defining parametrised constructor
Matrix::Matrix(int m, int n){
    rows = m;
    cols = n;
    ptr = new int* [m];
    for(int i =0;i<m;i++){
        ptr[i] = new int[n];
    }
}

//Defining oveloaded operator to take matrix as an input
istream & operator >>(istream &din , Matrix & m){
    for(int i =0;i<m.rows;i++){
        for(int j =0;j<m.cols;j++){
            din >> m.ptr[i][j];
        }
    }
    return din;
}

//Defining overoaded operator to display matrix 
ostream & operator << (ostream &dout,Matrix &m ){
    for(int i =0;i<m.rows;i++){
        for(int j = 0; j<m.cols;j++){
            dout<<setw(5)<< m.ptr[i][j];
        }
        dout<<endl;
    }
    return dout;
}

//Defining overloaded + opearator to add two matrices
Matrix Matrix::operator +(Matrix &m){
    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;
}

//Definig overloaded - operator to subtract two matrices
Matrix Matrix::operator -(Matrix &m){
    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;
}

//Defining overloaded *opeartor to perform matrix multiplication
Matrix Matrix::operator *(Matrix &m){
    Matrix temp(rows,cols);
    int product_sum;
    for(int i =0;i<rows;i++){
        for(int j=0;j<cols;j++){
            product_sum =0;
            for(int k=0;k<rows;k++){
                product_sum += ptr[i][k] * m.ptr[k][j];
            }
            temp.ptr[i][j] = product_sum;
        }
    }
    return temp;
}

//Defining overloaded = operator to assingn matrix value into another matrix  
Matrix Matrix::operator =(Matrix & m){
    for(int i =0;i<rows;i++){
        for(int j=0;j<cols;j++){
            ptr[i][j] = m.ptr[i][j];
        }
    }
    return *this;
}
//Definig a function to perform transpose of a matrix
void Matrix::transpose(Matrix &m){
    for(int i=0;i< rows;i++){
        for(int j=0;j<cols;j++){
            ptr[j][i] = m.ptr[i][j];
        }
    }
}
//Definig Destructor
Matrix::~Matrix(){
    for(int i=0;i<rows;i++){
        delete[] ptr[i];
    }
    delete[] ptr;
}
//Main Function
int main(){
    int row_1 ,row_2,col_1,col_2 ,chs;
    char choice , ch;
    cout<<"\n\n\t\t\t\t\tCreate Matrix A";
    cout<<"\nEnter the number of rows for matrix : ";
    cin>>row_1;
    cout<<"\nEnter the number of columns for matrix : ";
    cin>>col_1;
    Matrix A(row_1,col_1);
    cout<<"\nEnter the elements of Matrix row wise : ";
    cin >> A;
    cout<<"\nEntered Matrix \n";
    cout << A;
    cout<<"\n\n\t\t\tCreate Matrix B";
    cout<<"\nEnter the number of rows for matrix : ";
    cin>>row_2;
    cout<<"\nEnter the number of columns for matrix : ";
    cin>>col_2;
    Matrix B(row_2,col_2);
    cout<<"\nEnter the elements of Matrix row wise : ";
    cin >> B;
    cout<<"\nEntered Matrix\n";
    cout << B;
    Matrix C(col_1,row_1);
    C = A + B; //GETTING ERROR ON THIS LINE
    // **NO Operator "=" matches these operands , operand types -- Matrix = Matrix** 
    return 0;
}
  • 2
    Change parameter type from `Matrix &` to `const Matrix &`. – songyuanyao Nov 16 '21 at 08:05
  • 2
    You need to be far more generous with the `const`s. – molbdnilo Nov 16 '21 at 08:08
  • @songyuanyao Yeah! i tried that and it's started working to some extent, where i am taking matrix input but when its adding the two matrixes my program crashes showing (Segmentation fault Core dumped) I think there's some issue over memory logic in my code – vivek uniyal Nov 16 '21 at 08:47
  • Related/dupe: [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – Remy Lebeau Nov 16 '21 at 10:02

2 Answers2

0

The problem is this declaration:

Matrix Matrix::operator =(Matrix & m);

You should change it to:

Matrix Matrix::operator =(const Matrix & m)

The const reference prolongs the object's life; check this out for more details about extending an object's lifetime: Does a const reference class member prolong the life of a temporary?

EDIT: yous should also return Matrix&:

Matrix& Matrix::operator =(const Matrix & m)
kobi
  • 101
  • 7
  • i tried that and it's started working to some extent, where i am taking matrix input but when its adding the two matrices my program crashes showing __(Segmentation fault Core dumped)__ I think there's some issue over memory logic in my code – vivek uniyal Nov 16 '21 at 09:17
  • The return type needs to be `Matrix&` instead. An assignment operator is expected to return a *reference* to the object being assigned to. This code is returning a *copy* instead. – Remy Lebeau Nov 16 '21 at 10:00
  • In this case, `const&` does not prolong any object's life. As the top answer in the linked question states: "Only local const references prolong the lifespan." This is an argument in a function call; the lifespan of the `A+B` temporary is already the whole expression `C = A+B;` which contains that function call. – MSalters Nov 16 '21 at 10:03
  • Can you explain how your answer solves this problem? it's look like you suggest the same with the modification for my explenation. – kobi Nov 16 '21 at 11:14
  • __UPDATE = solved the issue . I understand where the problem is occuring in my code.the issue also lies on other operators overloading. There i have taken non const refrences in parameters in each case , which led to the loss in data modiication__ – vivek uniyal Nov 16 '21 at 13:35
0

Matrix Matrix::operator + returns a temporary. In C++, non-const references will not bind to temporaries. This is because a non-const reference generally is used to modify an object, and with a temporary such a modification would likely be lost.

But the overloaded assignment operator Matrix Matrix::operator =(Matrix & m) does not modify m, so it can really take a temporary by const&: Matrix Matrix::operator =(Matrix const& m).

Furthermore, the return type technically can be anything, even void, but in practice you should follow the behavior of the default operator and return Matrix& - a reference to *this, not a copy.

Also, if you used a std::vector as the backing store, you wouldn't need most of these utility methods at all!

MSalters
  • 173,980
  • 10
  • 155
  • 350