TITLE: The orthodox canonical class form PROBLEM: Question concerning the behaviour of the operator = for any given class and a suggested standard form for dealing with such problems is presented. Assume: class A { ... }; class B : public A { ... }; class C : public B { ... }; C c1, c2; RESPONSE: ??? What happens with "c1 = c2" ? - calls A::operator=(), B::operator=() and a memberwise copy for all NEW components of Class C - calls only B::operator=() and a memberwise copy for all NEW components of Class C - calls only B::operator=() and does a memberwise copy of ALL components of c1 without calling assignments of A and B - anything else ARM page 295 $12.8 [likewise the latest ANSI-C++ working papers] clearly states that unless explicitly defined by the programmer assignment defaults to mean memberwise assignment. [ ... deleted ... ] Note that if the rule were to naively inherit and reuse the assignment operators of one's immediate superclasses, then virtual base classes would be re-assigned multiple times, which would not be good. As a rule of thumb I suggest that programmers should "always" *explicitly* {uh-oh, I can hear the flames already} define the following four member functions for "each and every" C++ class: typically: default constructor Foo::Foo(); copy constructor taking a const ref Foo::Foo(const Foo&); [almost always virtual] destructor virtual Foo::~Foo(); assignment operator const Foo& Foo::operator=(const Foo&); ............................................................................ [ NOTE: this is referred to as the orthodox canonical form in "Advanced C++ Programming Styles and Idioms", by James Coplien. - ed] ............................................................................ The problems with letting the compiler automatically generating these things include: *some compilers still get them wrong *programmers assume that they're doing something they ain't *they come out inline when they shouldn't be, or vice versa *programmers define one of the constructors and a destructor, put debug statements in each of those -- and then complain [erroneously] that their compiler's busted. *some change in the super classes means the default member functions no longer work anymore, and since their isn't any explicit code in the subclass that's affected, no one notices until *much* later. So, a lot of old-time C++ hacks just automatically define all four of these things at the start of writing each and every new class. Also, if you can't define these four member functions so they make sense, it usually means you're conceptualizing your objects' store wrong. It's nice to be able to catch this fact before you write the rest of your [more complicated] member functions.