Operator overloading and inheritance

Discussion in 'C++' started by Steffen, Dec 9, 2005.

  1. Steffen

    Steffen Guest

    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;
    }
    Steffen, Dec 9, 2005
    #1
    1. Advertising

  2. 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;
    > }
    Neelesh Bodas, Dec 9, 2005
    #2
    1. Advertising

  3. 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::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
    Victor Bazarov, Dec 9, 2005
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cppsks
    Replies:
    2
    Views:
    1,279
    Markus Elfring
    Oct 27, 2004
  2. cppsks
    Replies:
    0
    Views:
    411
    cppsks
    Oct 27, 2004
  3. cppsks
    Replies:
    0
    Views:
    820
    cppsks
    Oct 27, 2004
  4. woosu
    Replies:
    6
    Views:
    3,616
    Victor Bazarov
    Jun 7, 2005
  5. Calvin Spealman
    Replies:
    0
    Views:
    726
    Calvin Spealman
    Sep 18, 2006
Loading...

Share This Page