Steffen
Guest
Posts: n/a

 12-09-2005
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:perator+(const Matrix&) const((&D2))'
matrix.cc:22: error: candidates are: DiagonalMatrix&
DiagonalMatrix: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: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: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;
}

Neelesh Bodas
Guest
Posts: n/a

 12-09-2005

Steffen wrote:
>
>
> 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.

> return 0;
> }

Victor Bazarov
Guest
Posts: n/a

 12-09-2005
Steffen wrote:
> 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:perator+(const Matrix&) const((&D2))'
> matrix.cc:22: error: candidates are: DiagonalMatrix&
> DiagonalMatrix: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