Operator overloading and inheritance

S

Steffen

Hi,

is there a simple way to use operators overloaded in some class for
objects of a derived class?

In my example I have a class Matrix that represents 2x2 matrices, and I
overloaded operator= and operator+ for this class. Then there is a
derived class DiagonalMatrix which represents diagonal 2x2-matrices. Now
I would like to use the operators = and + also for the diagonal
matrices, but the naive way doesn't work:

matrix.cc: In function `int main()':
matrix.cc:83: error: no match for 'operator=' in 'D3 =
Matrix::eek:perator+(const Matrix&) const((&D2))'
matrix.cc:22: error: candidates are: DiagonalMatrix&
DiagonalMatrix::eek:perator=(const DiagonalMatrix&)

Is there a way to do this without redefining these operators in the
derived class?


Thanks a lot
Steffen


Here is the code:

class Matrix
{
public:
Matrix(float m11=0, float m12=0, float m21=0, float m22=0);
Matrix(const Matrix &m);

virtual ~Matrix() {delete[] d;};

Matrix operator+(const Matrix &m) const;
Matrix& operator=(const Matrix &m);

float &c(int i, int j) const {return d[2*(i-1)+(j-1)];};

private:
float *d;
};



class DiagonalMatrix : public Matrix
{
public:
DiagonalMatrix() {};
DiagonalMatrix(float d1, float d2) {c(1,1) = d1; c(2,2) = d2;};
};




Matrix::Matrix(float m11, float m12, float m21, float m22)
{
d = new float[2*2];
c(1,1)=m11; c(1,2)=m12; c(2,1)=m21; c(2,2)=m22;
}

Matrix::Matrix(const Matrix &m)
{
d = new float[2*2];
for (int i=0 ; i<2 ; i++)
for (int j=0 ; j<2 ; j++)
c(i,j) = m.c(i, j);
}




Matrix Matrix::eek:perator+(const Matrix &q) const
{
Matrix r;

for (int i=1 ; i<=2 ; i++)
for (int j=1 ; j<=2 ; j++)
r.c(i,j) = c(i,j) += q.c(i,j);

return r;
}

Matrix& Matrix::eek:perator=(const Matrix &q)
{
for (int i=1 ; i<=2 ; i++)
for (int j=1 ; j<=2 ; j++)
c(i,j) = q.c(i,j);

return *this;
}


int main()
{
DiagonalMatrix D1(1,2);
DiagonalMatrix D2(3,4);
DiagonalMatrix D3;

D3 = D1 + D2; // this causes the error

return 0;
}
 
N

Neelesh Bodas

Steffen said:
int main()
{
DiagonalMatrix D1(1,2);
DiagonalMatrix D2(3,4);
DiagonalMatrix D3;

D3 = D1 + D2; // this causes the error

The return value of operator+ is a _value_ , not a reference or
pointer. So there is no legal conversion from the derived class _value_
to base class _value_. Hence the error.
 
V

Victor Bazarov

Steffen said:
is there a simple way to use operators overloaded in some class for
objects of a derived class?

In my example I have a class Matrix that represents 2x2 matrices, and I
overloaded operator= and operator+ for this class. Then there is a
derived class DiagonalMatrix which represents diagonal 2x2-matrices. Now
I would like to use the operators = and + also for the diagonal
matrices, but the naive way doesn't work:

matrix.cc: In function `int main()':
matrix.cc:83: error: no match for 'operator=' in 'D3 =
Matrix::eek:perator+(const Matrix&) const((&D2))'
matrix.cc:22: error: candidates are: DiagonalMatrix&
DiagonalMatrix::eek:perator=(const DiagonalMatrix&)

Is there a way to do this without redefining these operators in the
derived class?

It's generally a BAD IDEA(tm). First of all, your 'DiagonalMatrix' is not
necessarily properly derived. Think of this: a diagonal matrix has some
specific properties not all matrices have, right? Now, if I create some
algorithm that works on a "plain", unconstrained, Matrix, and then pass
a DiagonalMatrix to it, the algorithm can change the contents of my object
without concerning itself with the properties a diagonal matrix has, no?
It can simply add something off the main diagonal, and here you go, your
DiagonalMatrix object is not true any more.

So, whatever operation is performed by a member function of the base class
is not necessarily the right operation for the derived class, and that's
why you should think twice before allowing that.

But generally speaking, if you want to allow your operator+ that you wrote
for 'Matrix' to be used on a 'DiagonalMatrix', you will have to live with
the fact that it returns not a DiagonalMatrix, but only a Matrix. To make
it compile, define operator+ as NON-member. If you need it to be able to
access private data of Matrix objects, declare it a friend. That will
allow conversions (from DiagonalMatrix& to Matrix&) to be performed on
both operands, and not only on the right one.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top