TITLE: Assignment operators and virtual inheritance This C++ tip comes from "C++ Programming Style" by Tom Cargill, pages 194-204. It concerns multiple virtual inheritance and user-defined operators. All non-quoted material is paraphrased from the example in the book. .......................................................................... NON-VIRTUAL INHERITANCE Suppose we have the following heirarchy, shown in the diagram and code fragments below. Top / \ / \ / \ Left Right \ / \ / \ / Bottom class Top { int x; }; class Left : public Top { int y; public: Left& operator = (const Left&); }: class Right : public Top { int z; public: Right& operator = (const Right&); }: class Bottom : public Left, public Right { }; Left& Left :: operator = (const Left& rhs) // example assignment { if (this != &rhs) { this->Top::operator= (rhs); y = rhs.y; } return *this; } First note that an instance of a Bottom contains TWO instances of a Top due to the mutliple inheritance. An assignment of an instance of Left to Left (or Right to Right) will execute the Top assignment operation once during the Left assignment. A natural way to write the assignment for the class Bottom is to call the assignment operator for Left, for Right, then to assign the specific members of class Bottom. However, this results in TWO calls to the Top assignment operation. .......................................................................... VIRTUAL INHERITANCE To avoid the duplicate Top instance, we need to make two changes. First make Left and Right use virtual inheritance. class Left : public virtual Top { ... }; class Right : public virtual Top { ... }; The second change is to add a method to Left (and Right) to assign only the data members that are part of that class proper (not inherited from Top). The new assignment operators for Left (and Right) now look like void Left :: assignLocal (const Left& rhs) { y = rhs.y; } Left& Left :: operator = (const Left& rhs) { if (this != &rhs) { this->Top::operator= (rhs); assignLocal (rsh); } return *this; } "In general, an inheritance hierarchy involving virtual base classes must be constructed very carefully to ensure that all objects that can be instantiated from any class in the heirarchy behave consistently. As Ellis and Stroustrup understate on page 296, 'Such consistency is not easily achieved for, say, user-defined assignment operators.'"