virtual base class and construction/destruction order

Discussion in 'C++' started by BeautifulMind, Feb 6, 2007.

  1. In case of inheritence the order of execution of constructors is in
    the order of derivation and order of destructor execution is in
    reverse order of derivation.

    Is this case also true in case class is derived as virtual?

    How does the order of construction/destruction is impacted if the base
    class is derived as virtual or non virtual? just see the example
    below.

    I am using VS6/SP6. what the standard say on this.


    #include <iostream>
    using namespace std;

    class A
    {
    int val;
    public:
    ~A(){cout <<"~A()\n";}
    A() { cout <<"A()\n"; }
    };

    class B{
    int val;
    public:
    ~B(){cout <<"~B()\n";}
    B(){cout <<"B()\n";}
    };

    class C
    {
    int val;
    public:
    ~C(){cout <<"~C()\n";}
    C(){cout <<"C()\n";}
    };

    class F
    {
    int val;
    public:
    ~F(){cout <<"~F()\n";}
    F(){cout <<"F()\n";}
    };

    class D: public A, public B, public C, public F
    {
    int val;
    public:
    ~D(){cout <<"~D()\n";}
    D(){cout <<"D()\n";}

    };

    class K: public A, virtual public B, public C, public F
    {
    int val;
    public:
    ~K(){cout <<"~K()\n";}
    K(){cout <<"K()\n";}
    };


    class L: public A, virtual public B, virtual public C, public F
    {
    int val;
    public:
    ~L(){cout <<"~L()\n";}
    L(){cout <<"L()\n";}
    };

    int main()
    {
    {
    cout << "For D\n\n";
    D obj;
    }

    {
    cout << "For K\n\n";
    K obj;
    }

    {
    cout << "For L\n\n";
    L obj;
    }

    return 0;
    }
    /*
    Output is:


    For D

    A()
    B()
    C()
    F()
    D()
    ~D()
    ~F()
    ~C()
    ~B()
    ~A()

    For K

    B()
    A()
    C()
    F()
    K()
    ~K()
    ~F()
    ~C()
    ~A()
    ~B()

    For L

    B()
    C()
    A()
    F()
    L()
    ~L()
    ~F()
    ~A()
    ~C()
    ~B()

    */
     
    BeautifulMind, Feb 6, 2007
    #1
    1. Advertisements

  2. * BeautifulMind:
    Yes.

    The only problem is that the virtual base class' constructor arguments
    must be specified (explicitly, or for a default constructor implicitly)
    by the most derived class.

    That's because there's only a single call of that constructor, and the
    various specifications in not-most-derived-classes could easily conflict.
     
    Alf P. Steinbach, Feb 6, 2007
    #2
    1. Advertisements

  3. BeautifulMind

    Markus Moll Guest

    Hi
    It says that
    a) virtual base classes are initialized in the most derived class
    b) virtual base classes are initialized first
    c) the order is determined by the order of appearance in a depth-first
    search through the inheritance graph.

    For example,

    A : virtual B, C
    B : D, virtual E
    C : virtual F, G

    corresponds to the following graph:
    A
    / \
    / \
    B C
    / \ / \
    D E F G

    Let's see... When doing the depth-first search, we find the virtual base
    classes in the following order:
    E, B, F
    So E will be initialized first. Next is B, but this requires prior
    initialization of D. So the order of initialization will be
    E, D, B, F, G, C, A
    As usual, the order is reversed at destruction.

    Markus
     
    Markus Moll, Feb 6, 2007
    #3
  4. BeautifulMind

    Ron Natalie Guest

    The destruction is the reverse of construction.

    The order of construction is well defined and is paraphrased here:

    1. First all the virtual base classes are constructed.

    Then starting at the most derived class, and running recursively

    2. The classes direct non-virtual bases are constructed
    3. The non-static class members are constructed
    4. The constructor body is executed.
     
    Ron Natalie, Feb 6, 2007
    #4

  5. For a class, the order of the member initialization list has to match
    the order of declarations within the class. Does this rule apply when
    we pass arguments to base class constructors?

    what is the correct order of including the the following in member
    initilization list (if this order really matter):
    1. non constant and const data members of a class
    2. virtual base classes
    3. non-virtual base class

    Regards,
    BeautifulMind
     
    BeautifulMind, Feb 7, 2007
    #5
  6. Reporting for clarity:-

    For a class, the order of the member initialization list should match
    the order of declarations within the class. Does this rule apply when
    we pass arguments to base class constructors in member initialization
    list?

    What is the correct order of including the following in member
    initialization list (if this order really matter):

    1. Non-constant and const data members of a class
    2. Virtual base class constructors
    3. Non-virtual base class constructors

    Regards,
    BeautifulMind
     
    BeautifulMind, Feb 7, 2007
    #6

  7. Thanks for the nice explanation Markus
     
    BeautifulMind, Feb 8, 2007
    #7
  8. BeautifulMind

    Ron Natalie Guest

    Nothing changes the order of initialization from what I stated.
    Not the passing of arguments, not the presence of member initializers.
    As I said before, the virtual base classes are initialized before
    all others.

    Then starting at the most derived class:
    The direct bases (non-virtual) are initialized
    The non-static members
    Then the constructor body runs.

    Const makes no difference to initialization or destruction.
     
    Ron Natalie, Feb 8, 2007
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.