[comp.lang.c++] default and user-defined assignment operator problems

herman@kulcs.uucp (Herman Moons) (07/23/90)

I've got a problem with the assignment operator when class derivation
is used (probably my lack of understanding).

Suppose we have the following inheritance graph

class Base       ==> redefines operator=
    |
class Derived  
    |
class DDerived   ==> redefines operator=


Since class Derived doesn't provide its own version of operator=, the
C++ compiler provides a default one (memberwise assignment).  However,
since class DDerived defines its own operator=, this one is used to
assign one DDerived object to another.  The DDerived::operator= is now
responsible for assigning its bases and members.

Problem: to assign the Derived base part, I use the following:

         DDerived& DDerived::operator= (DDerived& d) {
              Derived::operator= (d);
              //...
         }

         In my opinion this means that the Derived::operator= should be
         used to assing the Derived base class part.  Since I haven't
         redefined it, the default version should be used (with memberwise
         assignment).

I tried this with g++ v1.36, and it didn't behave the way I expected.  I alse
tried it on a PC with Zortech C++ v2.0, and it also produced unexpected
results.

Is there a hole in my reasoning, and if so, what is it ?????  


herman.

----------------------------------------------------------------------
#include <stdio.h>

class Base {
public:
    Base (int i) { 
        base = i; 
    }
    Base& operator= (Base& b) { 
        base = b.base; 
        printf( "Base::operator= called\n" );
    }
    int base;
};

class Derived : public Base {
public:
    Derived (int i) : Base(i+1), db(i+20) { 
        der = i; 
    }
//    Derived& operator= (Derived& d) {
//        Base::operator= (d);
//        der = d.der;
//    }
    void print() {
        printf("(base,der,db) = (%d,%d,%d)\n",base,der,db.base);
    }
    int der;
    Base db;
};

class DDerived : public Derived {
public:
    DDerived (int i) : Derived(i+1) {
        dder = i;
    }
    DDerived& operator= (DDerived& d) {
        Derived::operator= (d); // SHOULD THIS CALL THE COMPILER GENERATED
                                // MEMBERWISE COPY ASSIGNMENT OPERATOR ???
        dder = d.dder;
        printf( "DDerived::operator= called\n" );
    }
    void print() {
        printf("(base,der,db,dder) = (%d,%d,%d,%d)\n",base,der,db.base,dder);
    }
    int dder;
};


main()
{
    Derived x1(1), x2(2);

    printf ("*** before assignment ***\n");
    x1.print();
    x2.print();

    x1 = x2;

    printf ( "*** after assignment ***\n" );
    x1.print();
    x2.print();

    DDerived d1(1), d2(2);

    printf( "*** before assignment ***\n");
    d1.print();
    d2.print();

    d1 = d2;

    printf( "*** after assignment ***\n");
    d1.print();
    d2.print();
}
-----------------------------------------------------------------------

output produced by g++ 1.36

*** before assignment ***
(base,der,db) = (2,1,21)
(base,der,db) = (3,2,22)
Base::operator= called
Base::operator= called
*** after assignment ***
(base,der,db) = (3,2,22)
(base,der,db) = (3,2,22)
*** before assignment ***
(base,der,db,dder) = (3,2,22,1)
(base,der,db,dder) = (4,3,23,2)
Base::operator= called
DDerived::operator= called
*** after assignment ***
(base,der,db,dder) = (4,2,22,2)
(base,der,db,dder) = (4,3,23,2)
                       +----+
                          the members of base class Derived are NOT
                          memberwise assigned !!!



-----------------------------------------------------------------------------
Herman Moons                                   Katholieke Universiteit Leuven
                                               Dept. of Computer Science
Tf : +32 (16) 20.06.56                         Celestijnenlaan 200A
Fax: +32 (16) 20.53.08                         B-3030 Heverlee-Leuven
                                               Belgium
e-mail: herman@kulcs.uucp
	herman@blekul60.bitnet
	herman@cs.kuleuven.ac.be

-----------------------------------------------------------------------------