Nektar Nektar - 28 days ago 5
C++ Question

Matrix Class implementation

I am totally new to C++ and trying to implement a Matrix class with arithmetic operator implementation. But I am getting an error while implementing "+= or -= or *=" operator. The error is: error: no match for 'operator[]' (operand types are 'const Matrix' and 'int')

#include<iostream>
#include <cstdlib>
#include<cassert>
using namespace std;

class Matrix
{
public:
// constructor
Matrix(int rows,int cols, double initial)
{
if(rows>0 && cols >0){
Matdata = new double*[rows];

for (int i = 0; i <rows; i++)
{
Matdata[i] = new double[cols];
for(int j=0;j <cols;j++)
{
Matdata[i][j] = initial;
}
}
}
}

Matrix& operator +=(const Matrix& rhs)
{
rows = rhs.rows;
cols = rhs.rows;
for (int i=0; i<rows; i++) {
for (int j=0; j<cols; j++) {
this->Matdata[i][j] += this->Matdata[i][j] + rhs[i][j]; // error in this line
}
}
return *this;
}
//
private:
double **Matdata;
int rows;
int cols;

};


and the Main function is like :

int main(int argc, char** argv)
{
testArithmeticOperators();
testCopy();
}

where
void testCopy()
{

Matrix m1( 3,4,1.0 );
Matrix m2( 3,4,2.0 );
m2 = m1;

}

void testArithmeticOperators()
{
Matrix m1( 2,2,0.0 );
Matrix m2( 2,2,0.0 );
Matrix sum ( m1+m2 );
Matrix prod ( m1*m2 );
m1 += m2;
m1 -= m1;
}

Answer

The issue is that your operator+ has the following signature:

 Matrix& operator +=(const Matrix& rhs)

The problem is that rhs has no operator[] defined for it when you do this:

this->Matdata[i][j] += this->Matdata[i][j] + rhs[i][j]

The fix is simply to use rhs.Matdata[i][j], since rhs.Matdata is the underlying double** of the passed-in parameter:

this->Matdata[i][j] += this->Matdata[i][j] + rhs.Matdata[i][j];

On some implementation issues, your operator= could simply be the following:

Matrix& operator=(const Matrix& rhs) 
{
    Matrix temp(rhs);
    std::swap(temp.Matdata, Matdata);
    std::swap(temp.rows, rows);
    std::swap(temp.cols, cols);
    return *this;
}

Since you have a copy constructor and destructor for Matrix, the copy / swap idiom can be used to easily implement the assignment operator.

The second implementation issue is that your operator+ should be implemented in terms of operator+=, and not have to rewrite what operator+= does. When you do that, operator+ turns into a 1 line function:

 Matrix operator+(const Matrix& rhs)
 {
    return Matrix(*this) += rhs;
 }

This uses the copy constructor to create a temporary Matrix and the existing operator += to add the rhs onto the temporary. You should make similar changes in implementing operator -, ooperator *, etc. in that you first implement operator -=, operator *=.