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 -----------------------------------------------------------------------------