80 likes | 221 Views
C++ Addendum: Multiple and Virtual Inheritance in C++. Initialization of Virtual Bases Frozen Classes in C++ Construction Order with MI. Constructors and Virtual Base Class?. Consider the following situation:. class V { public : V( const char *s){ cout << s;} };.
E N D
C++ Addendum:Multiple and Virtual Inheritance in C++ • Initialization of Virtual Bases • Frozen Classes in C++ • Construction Order with MI oop
Constructors and Virtual Base Class? Consider the following situation: class V { public: V(const char *s){ cout << s;}}; class B1: public virtual V { public: B1(const char *s): V("B1"){ cout << s; }}; class B2: public virtual V { public: B2(const char *s): V("B2"){ cout << s; }}; class D: public B1, public B2 { public: D(void): B1("DB1"), B2("DB2") {}} d; What will be printed? oop
Construction of a Virtual Base Class • Answer: nothing will be printed. The compiler will issue an error message. • Work around 1: • Define a default constructor in V • Work around 2: • Call V’s constructor directly from the constructor of D • Virtual bases are initialized by the initializer of the most derived class, other initializers are ignored • Virtual bases may be initialized in a constructor of a derived class even if they are not immediate base classes • Comments: • All virtual inheritances of the same base are unified. • All non virtual inheritances of the same base are distinct. oop
Virtual Base Initilization class V { public: V(); V(int); ... }; class A: publicvirtual V { public: A(); A(int i): V(i) { /* ... */ } ... }; class B : publicvirtual V { public: B(); B(int i) { /* ... */ } ... }; class C : public A, public B { public: C(int i): V(i) { /* ... */ } ... }; V v(1); // use V(int) A a(2); // use V(int) B b(3); // use V() C c(4); // use V(int) oop
Frozen Classes in C++ #ifndef ICE struct ice__ { ice__(void){}; // Constructor}; #define ICE privatevirtual ice__ #endif ICE ice.h #include "ice.h" class Frozen: ICE { // ... } var; class Violation: public Frozen { // ... }; The trick may be easily worked around by deriving the Violation class from ice__ Error: ice__::ice__() is not accessible in function Violation::Violation() oop
Construction and Multiple Inheritance • Elements to initialize: sub-objects, reference data members, const members, and all other data members. • Where to initialize? best in constructor header (only other data members can be initialized in constructor body). • Order of initializers in constructor header: unrelated to actual initialization sequence; this makes it possible to guarantee that the construction order is the exact opposite of destruction order. • Construction Order: recursive algorithm • Virtual base classes: immediate and non-immediate • Order is as they occur on a depth-first, left-to-right traversal of the DAG of base classes. • If a virtual base class is derived from a non-virtual base, then this non-virtual base will be constructed before this virtual base is constructed. • Other base-classes (in order of definition). • Data members (in order of definition). • Constructor body • Order of destruction is the same in reverse. oop
Initialization Order Algorithm • Apply topological sort ranking inheritance DAG in a depth-first, left-right scan • Virtual and non-virtual inheritance are treated alike. • Construct all virtual base classes (immediate and non-immediate) • Use ranking order. • Do not construct twice. • Apply recursively to construct their non-virtual bases. • Construct non-virtual immediate base classes: • Use ranking order (same asdefinition order). • Apply recursively to construct their non-virtual bases. • Construction order in example: U1 U2 Y X V2 V1 V3 V4 B1 B2 D • Destruction order in example: D B2 B1 V4 V3 V1 V2 X Y U2 U1 oop