/* * initializing-virtual-bases.cc * * This example illustrates how construction of subobjects in a class * lattice with virtual base classes is done. Trace print-outs from * constructors and destructors shows construction and destruction * order. */ #include using namespace std; struct Member_1 { Member_1(int i) : i_(i) { cout << " Member_1 subobject initialized: i = " << i << endl; } ~Member_1() { cout << " Member_1 subobject destroyed" << endl; } int i_; }; struct Member_2 { Member_2(int i) : i_(i) { cout << " Member_2 subobject initialized: i = " << i << endl; } ~Member_2() { cout << " Member_2 subobject destroyed" << endl; } int i_; }; struct Member_3 { Member_3(int i) : i_(i) { cout << " Member_3 subobject initialized: i = " << i << endl; } ~Member_3() { cout << " Member_3 subobject destroyed" << endl; } int i_; }; struct Base_1 { Base_1(int m1) : m1_(m1) { cout << " Base_1 subobject initialized: m = " << m1 << endl; } ~Base_1() { cout << " Base_1 subobject destroyed" << endl; } int get_value() const { return m1_.i_; } Member_1 m1_; }; struct Base_2 { Base_2(int m2) : m2_(m2) { cout << " Base_2 subobject initialized: m = " << m2 << endl; } ~Base_2() { cout << " Base_2 subobject destroyed" << endl; } int get_value() const { return m2_.i_; } Member_2 m2_; }; struct Base_3 { Base_3(int m3) : m3_(m3) { cout << " Base_3 subobject initialized: m = " << m3 << endl; } ~Base_3() { cout << " Base_3 subobject destroyed" << endl; } int get_value() const { return m3_.i_; } Member_3 m3_; }; struct Virtual_1 : public Base_2, public Base_3 { Virtual_1(int b2, int b3, int m1) : Base_2(b2), Base_3(b3), m1_(m1) { cout << " Virtual_1 subobject initialized: m = " << m1 << endl; } ~Virtual_1() { cout << " Virtual_1 subobject destroyed" << endl; } Member_1 m1_; }; struct Virtual_2 : public Base_1, public Base_3 { Virtual_2(int b1, int b3) : Base_1(b1), Base_3(b3) { cout << " Virtual_2 subobject initialized: s = " << s2_.i_ << endl; } ~Virtual_2() { cout << " Virtual_2 subobject destroyed" << endl; } static Member_2 s2_; }; Member_2 Virtual_2::s2_(0); // The initializer for Virtual_1 is ignored when initializing an object of type subclass // to Derived_1. struct Derived_1 : public Base_1, virtual public Virtual_1 { Derived_1(int v11, int v12, int v13, int b1) : Virtual_1(v11, v12, v13), Base_1(b1) { cout << " Derived_1 subobject initialized" << endl; } ~Derived_1() { cout << " Derived_1 subobject destroyed" << endl; } }; // The initializer for Virtual_2 is ignored when initializing an object of type subclass // to Derived_2. struct Derived_2 : virtual public Virtual_1 { Derived_2(int v11, int v12, int v13, int m2) : Virtual_1(v11, v12, v13), m2_(m2) { cout << " Derived_2 subobject initialized: m2_ = " << m2 << endl; } ~Derived_2() { cout << " Derived_2 subobject destroyed" << endl; } Member_2 m2_; }; // The initializers for Virtual_1 and Virtual_2 are ignored when initializing an object // of type subclass to Derived_3. struct Derived_3 : public Derived_1, public Derived_2, virtual public Virtual_2 { Derived_3(int v11, int v12, int v13, int v21, int v22, int m1, int m2, int m3) : Virtual_1(v11, v12, v13), Virtual_2(v21, v22), Derived_1(v11, v12, v13, m1), Derived_2(v11, v12, v13, m2), m3_(m3) { cout << " Derived_3 subobject initialized: m = " << m3_.i_ << endl; } ~Derived_3() { cout << " Derived_3 subobject destroyed" << endl; } Member_3 m3_; }; // The initializers for Virtual_1 and Virtual_2 are used when initializing an object of // type Most_Derived (such as x below). Initializers for Virtual_1 and Virtual_2 in the // base classes to Most_Derived are ignored. struct Most_Derived : public Derived_3 { Most_Derived() : Virtual_1(11, 12, 13), Virtual_2(21, 22), Derived_3(311, 312, 313, 321, 322, 301, 302, 303), m2_(2), m3_(3) { cout << " Most_Derived object initialized" << endl; } ~Most_Derived() { cout << " Most_Derived object destroyed" << endl; } using Base_2::get_value; static Member_1 s1_; Member_2 m2_; Member_3 m3_; }; Member_1 Most_Derived::s1_(0); int main() { cout << "\nTraces from initialization if the object x (Most_Derived):" << endl; Most_Derived x; cout << "\nx.get_value() = " << x.get_value() << endl; cout << "\nTraces from destruction of x and static objects (last):" << endl; return 0; }