I am struggling to get my head around operator overloading. In this case the + operator I have and example of what I have tried, any help would be greatly appreciated.
I am getting an error which says "invaild use of 'class Matrix' I am unsure on how to fix this how can I add these two Matrix objects together?
Matrix Matrix::operator+(const Matrix& rhs){
return Matrix(Matrix + rhs.Matrix());
}
Matrix::Matrix(int MM, int NN){
M = MM;
N = NN;
data = new double[M * N];
for ( int i =0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
data[i* N+j] = (double) 1000 + i*N+j;
// cout << data[i*N+j] <<"\t";
}
//cout <<"\n";
}
cout << "Matrix Constructor... (code to be implemented here!!!)\n";}
Thanks
-
a good read about operator overloading courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.htmlMarius– Marius2012年04月06日 12:31:23 +00:00Commented Apr 6, 2012 at 12:31
3 Answers 3
- rhs is a
Matrix - calling a constructor like a method is very illegal
- in
Matrix + rhs,Matrixis not an identifier - Once you get your identifiers straightened out,
*this + rhsis equivalent tothis->operator+(rhs). It should be obvious from this that all you've done here is create an infinite recursion.
4 Comments
data member via heap memory by using new in your constructor (and presumably a corresponding deletein your destructor), you should define a copy constructor and assignment operator that does a proper deep copy of the data, as the default ones C++ provides can lead to problems like multiple Matrix instances referencing the same data pointer (if copied) and dangling pointer problems on copies.Matrix is an identifier, it just names a type and not a variable.jpm's answer is very important to look at. Once you've fixed these things, you can look at mine.
Essentially, an operator overload is no different than any other function.
So, in the case of:
Matrix Matrix::operator+(const Matrix& rhs)
What you're really doing there is saying: add rhs to the current matrix, and return a new matrix. Your overload should not alter the current matrix. Help yourself and use a constant:
Matrix Matrix::operator+(const Matrix& rhs) const
A matrix addition like that should first check if the matrices have the same dimensions so that you can add them together, then loop through all "cells" and add them, and create a matrix out of that. For that, I'm guessing you'll need a second constructor, something like:
Matrix::Matrix(int MM, int NN, double values[])
{
M = MM;//TODO: change to width
N = NN;//TODO: change to height
data = new double[M*N];
for(int i < 0; i < M; i++)
for(int j < 0; j < N; j++)
data[i * N+j] = values[i * N+j];
}
1 Comment
return Matrix(Matrix + rhs.Matrix());
^^^^^^ ^^^^^^
You're using a type name (Matrix) where there should be an expression - that's what the compiler is complaining about. You're also trying to call the constructor on an existing object, which is invalid (and nonsensical). You also seem to be trying to implement operator+ in such a way that it calls itself; if you do somehow make it compile, then it will cause a stack overflow due to infinite recursion.
Perhaps the easiest way to implement addition is to implement operator+= to add one matrix to an existing one, and then implement operator+ in terms of that:
Matrix & Matrix::operator+=(Matrix const & rhs) {
// Perform addition here
for (int i = 0; i < N*M; ++i) {
data[i] += rhs.data[i];
}
return *this;
}
// This can be a non-member function
// Pass "lhs" by value to get a copy, then modify and return that.
Matrix operator+(Matrix lhs, Matrix const & lhs) {
return lhs += rhs;
}
// Or if you really want a member function for some reason
Matrix Matrix::operator+(Matix const & rhs) const {
return Matrix(*this) += rhs;
}
This does require you to have a correct copy constructor - since you're allocating memory yourself in the constructor, and presumably deallocating it in the destructor, you must implement a copy-constructor to correctly allocate new memory (per the Rule of Three), otherwise you'll get a double-deletion after copying a matrix.