order of constructor execution...

Discussion in 'C++' started by Rahul, Dec 19, 2007.

  1. Rahul

    Rahul Guest

    Hi Everyone,

    I was trying to understand the constructor order execution and i
    tried the following example,

    #include <stdio.h>

    class A
    {
    public: A()
    {
    printf("A\n");
    }
    };

    class D
    {
    public : D()
    {
    printf("D\n");
    }
    D(int i)
    {
    printf("D is %d\n",i);
    }
    };

    class E
    {
    public: E()
    {
    printf("E\n");
    }
    E(int i)
    {
    printf("E is %d\n",i);
    }
    };

    class C : virtual public E, virtual public D
    {
    public: C()
    {
    printf("C\n");
    }
    C(int a) : D(a), E(a)
    {
    printf("C is %d\n",a);
    }
    };

    class B : public A, public C
    {
    C c_obj;
    public: B() : C(5), c_obj(10)
    {
    printf("B\n");
    }
    };

    int main()
    {
    B obj;
    return (0);
    }

    I get the following output,

    E // virtual base (left to right)
    D // virtual base (left to right)
    A // base class
    C is 5 // base class
    E is 10 // member object
    D is 10 // member object
    C is 10 // member object
    B // constructor


    Yes, the virtual base class constructors (default) are invoked first
    for obj as expected.
    However, for the member object c_obj, the virtual base class
    constructors aren't invoked ( i mean the default constructor of E and
    D) instead the second version ( accepting an integer ) is called?

    Is there any special rule for member objects as far as initialization
    of virtual base classes are concerned?
     
    Rahul, Dec 19, 2007
    #1
    1. Advertising

  2. Rahul

    Craig Scott Guest

    On Dec 19, 10:43 pm, Rahul <> wrote:
    > Hi Everyone,
    >
    > I was trying to understand the constructor order execution and i
    > tried the following example,
    >
    > #include <stdio.h>
    >
    > class A
    > {
    > public: A()
    > {
    > printf("A\n");
    > }
    >
    > };
    >
    > class D
    > {
    > public : D()
    > {
    > printf("D\n");
    > }
    > D(int i)
    > {
    > printf("D is %d\n",i);
    > }
    >
    > };
    >
    > class E
    > {
    > public: E()
    > {
    > printf("E\n");
    > }
    > E(int i)
    > {
    > printf("E is %d\n",i);
    > }
    >
    > };
    >
    > class C : virtual public E, virtual public D
    > {
    > public: C()
    > {
    > printf("C\n");
    > }
    > C(int a) : D(a), E(a)
    > {
    > printf("C is %d\n",a);
    > }
    >
    > };
    >
    > class B : public A, public C
    > {
    > C c_obj;
    > public: B() : C(5), c_obj(10)
    > {
    > printf("B\n");
    > }
    >
    > };
    >
    > int main()
    > {
    > B obj;
    > return (0);
    >
    > }
    >
    > I get the following output,
    >
    > E // virtual base (left to right)
    > D // virtual base (left to right)
    > A // base class
    > C is 5 // base class
    > E is 10 // member object
    > D is 10 // member object
    > C is 10 // member object
    > B // constructor
    >
    > Yes, the virtual base class constructors (default) are invoked first
    > for obj as expected.
    > However, for the member object c_obj, the virtual base class
    > constructors aren't invoked ( i mean the default constructor of E and
    > D) instead the second version ( accepting an integer ) is called?


    Why should the default constructors be called? You specify the non-
    default constructors in your initialization list, so those will be
    used. As you correctly observe, virtual base classes are initialized
    before all other base classes and this is done in the order they are
    listed in the class definition.

    > Is there any special rule for member objects as far as initialization
    > of virtual base classes are concerned?


    The C++ standard explicitly states what is happening in your example
    in 12.6.2/6:

    "All sub-objects representing virtual base classes are initialized by
    the constructor of the most derived class (1.8). If the constructor of
    the most derived class does not specify a mem-initializer for a
    virtual base class V, then V's default constructor is called to
    initialize the virtual base class subobject."

    And you *do* supply a mem-initializer for the virtual bases of C for
    the C(int) constructor, so those are used when you create your B
    object in main() because B uses the C(int) constructor for its c_obj
    data member.

    --
    Computational Modeling, CSIRO (CMIS)
    Melbourne, Australia
     
    Craig Scott, Dec 19, 2007
    #2
    1. Advertising

  3. Rahul

    Rahul Guest

    On Dec 19, 5:20 pm, Craig Scott <> wrote:
    > On Dec 19, 10:43 pm, Rahul <> wrote:
    >
    >
    >
    > > Hi Everyone,

    >
    > > I was trying to understand the constructor order execution and i
    > > tried the following example,

    >
    > > #include <stdio.h>

    >
    > > class A
    > > {
    > > public: A()
    > > {
    > > printf("A\n");
    > > }

    >
    > > };

    >
    > > class D
    > > {
    > > public : D()
    > > {
    > > printf("D\n");
    > > }
    > > D(int i)
    > > {
    > > printf("D is %d\n",i);
    > > }

    >
    > > };

    >
    > > class E
    > > {
    > > public: E()
    > > {
    > > printf("E\n");
    > > }
    > > E(int i)
    > > {
    > > printf("E is %d\n",i);
    > > }

    >
    > > };

    >
    > > class C : virtual public E, virtual public D
    > > {
    > > public: C()
    > > {
    > > printf("C\n");
    > > }
    > > C(int a) : D(a), E(a)
    > > {
    > > printf("C is %d\n",a);
    > > }

    >
    > > };

    >
    > > class B : public A, public C
    > > {
    > > C c_obj;
    > > public: B() : C(5), c_obj(10)
    > > {
    > > printf("B\n");
    > > }

    >
    > > };

    >
    > > int main()
    > > {
    > > B obj;
    > > return (0);

    >
    > > }

    >
    > > I get the following output,

    >
    > > E // virtual base (left to right)
    > > D // virtual base (left to right)
    > > A // base class
    > > C is 5 // base class
    > > E is 10 // member object
    > > D is 10 // member object
    > > C is 10 // member object
    > > B // constructor

    >
    > > Yes, the virtual base class constructors (default) are invoked first
    > > for obj as expected.
    > > However, for the member object c_obj, the virtual base class
    > > constructors aren't invoked ( i mean the default constructor of E and
    > > D) instead the second version ( accepting an integer ) is called?

    >
    > Why should the default constructors be called? You specify the non-
    > default constructors in your initialization list, so those will be
    > used. As you correctly observe, virtual base classes are initialized
    > before all other base classes and this is done in the order they are
    > listed in the class definition.
    >
    > > Is there any special rule for member objects as far as initialization
    > > of virtual base classes are concerned?

    >
    > The C++ standard explicitly states what is happening in your example
    > in 12.6.2/6:
    >
    > "All sub-objects representing virtual base classes are initialized by
    > the constructor of the most derived class (1.8). If the constructor of
    > the most derived class does not specify a mem-initializer for a
    > virtual base class V, then V's default constructor is called to
    > initialize the virtual base class subobject."
    >
    > And you *do* supply a mem-initializer for the virtual bases of C for
    > the C(int) constructor, so those are used when you create your B
    > object in main() because B uses the C(int) constructor for its c_obj
    > data member.
    >
    > --


    Ok, so this is standard for member objects but not for base class
    constructors, like C(5)
    doesn't invoke E(5) and D(5) instead calls the default constructor of
    D and E... but why is this so?
     
    Rahul, Dec 19, 2007
    #3
  4. Rahul wrote:
    > On Dec 19, 5:20 pm, Craig Scott <> wrote:
    >> On Dec 19, 10:43 pm, Rahul <> wrote:
    >>
    >>
    >>
    >>> Hi Everyone,

    >>
    >>> I was trying to understand the constructor order execution and i
    >>> tried the following example,

    >>
    >>> #include <stdio.h>

    >>
    >>> class A
    >>> {
    >>> public: A()
    >>> {
    >>> printf("A\n");
    >>> }

    >>
    >>> };

    >>
    >>> class D
    >>> {
    >>> public : D()
    >>> {
    >>> printf("D\n");
    >>> }
    >>> D(int i)
    >>> {
    >>> printf("D is %d\n",i);
    >>> }

    >>
    >>> };

    >>
    >>> class E
    >>> {
    >>> public: E()
    >>> {
    >>> printf("E\n");
    >>> }
    >>> E(int i)
    >>> {
    >>> printf("E is %d\n",i);
    >>> }

    >>
    >>> };

    >>
    >>> class C : virtual public E, virtual public D
    >>> {
    >>> public: C()
    >>> {
    >>> printf("C\n");
    >>> }
    >>> C(int a) : D(a), E(a)
    >>> {
    >>> printf("C is %d\n",a);
    >>> }

    >>
    >>> };

    >>
    >>> class B : public A, public C
    >>> {
    >>> C c_obj;
    >>> public: B() : C(5), c_obj(10)
    >>> {
    >>> printf("B\n");
    >>> }

    >>
    >>> };

    >>
    >>> int main()
    >>> {
    >>> B obj;
    >>> return (0);

    >>
    >>> }

    >>
    >>> I get the following output,

    >>
    >>> E // virtual base (left to right)
    >>> D // virtual base (left to right)
    >>> A // base class
    >>> C is 5 // base class
    >>> E is 10 // member object
    >>> D is 10 // member object
    >>> C is 10 // member object
    >>> B // constructor

    >>
    >>> Yes, the virtual base class constructors (default) are invoked
    >>> first for obj as expected.
    >>> However, for the member object c_obj, the virtual base class
    >>> constructors aren't invoked ( i mean the default constructor of E
    >>> and D) instead the second version ( accepting an integer ) is
    >>> called?

    >>
    >> Why should the default constructors be called? You specify the non-
    >> default constructors in your initialization list, so those will be
    >> used. As you correctly observe, virtual base classes are initialized
    >> before all other base classes and this is done in the order they are
    >> listed in the class definition.
    >>
    >>> Is there any special rule for member objects as far as
    >>> initialization of virtual base classes are concerned?

    >>
    >> The C++ standard explicitly states what is happening in your example
    >> in 12.6.2/6:
    >>
    >> "All sub-objects representing virtual base classes are initialized by
    >> the constructor of the most derived class (1.8). If the constructor
    >> of the most derived class does not specify a mem-initializer for a
    >> virtual base class V, then V's default constructor is called to
    >> initialize the virtual base class subobject."
    >>
    >> And you *do* supply a mem-initializer for the virtual bases of C for
    >> the C(int) constructor, so those are used when you create your B
    >> object in main() because B uses the C(int) constructor for its c_obj
    >> data member.
    >>
    >> --

    >
    > Ok, so this is standard for member objects but not for base class
    > constructors, like C(5)
    > doesn't invoke E(5) and D(5) instead calls the default constructor of
    > D and E... but why is this so?


    Why should it be NOT so? How should the compiler know that you
    intend to pass the 5 along to the base classes and not 5*rand() ?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Dec 19, 2007
    #4
  5. Rahul

    Rahul Guest

    On Dec 19, 8:51 pm, "Victor Bazarov" <> wrote:
    > Rahul wrote:
    > > On Dec 19, 5:20 pm, Craig Scott <> wrote:
    > >> On Dec 19, 10:43 pm, Rahul <> wrote:

    >
    > >>> Hi Everyone,

    >
    > >>> I was trying to understand the constructor order execution and i
    > >>> tried the following example,

    >
    > >>> #include <stdio.h>

    >
    > >>> class A
    > >>> {
    > >>> public: A()
    > >>> {
    > >>> printf("A\n");
    > >>> }

    >
    > >>> };

    >
    > >>> class D
    > >>> {
    > >>> public : D()
    > >>> {
    > >>> printf("D\n");
    > >>> }
    > >>> D(int i)
    > >>> {
    > >>> printf("D is %d\n",i);
    > >>> }

    >
    > >>> };

    >
    > >>> class E
    > >>> {
    > >>> public: E()
    > >>> {
    > >>> printf("E\n");
    > >>> }
    > >>> E(int i)
    > >>> {
    > >>> printf("E is %d\n",i);
    > >>> }

    >
    > >>> };

    >
    > >>> class C : virtual public E, virtual public D
    > >>> {
    > >>> public: C()
    > >>> {
    > >>> printf("C\n");
    > >>> }
    > >>> C(int a) : D(a), E(a)
    > >>> {
    > >>> printf("C is %d\n",a);
    > >>> }

    >
    > >>> };

    >
    > >>> class B : public A, public C
    > >>> {
    > >>> C c_obj;
    > >>> public: B() : C(5), c_obj(10)
    > >>> {
    > >>> printf("B\n");
    > >>> }

    >
    > >>> };

    >
    > >>> int main()
    > >>> {
    > >>> B obj;
    > >>> return (0);

    >
    > >>> }

    >
    > >>> I get the following output,

    >
    > >>> E // virtual base (left to right)
    > >>> D // virtual base (left to right)
    > >>> A // base class
    > >>> C is 5 // base class
    > >>> E is 10 // member object
    > >>> D is 10 // member object
    > >>> C is 10 // member object
    > >>> B // constructor

    >
    > >>> Yes, the virtual base class constructors (default) are invoked
    > >>> first for obj as expected.
    > >>> However, for the member object c_obj, the virtual base class
    > >>> constructors aren't invoked ( i mean the default constructor of E
    > >>> and D) instead the second version ( accepting an integer ) is
    > >>> called?

    >
    > >> Why should the default constructors be called? You specify the non-
    > >> default constructors in your initialization list, so those will be
    > >> used. As you correctly observe, virtual base classes are initialized
    > >> before all other base classes and this is done in the order they are
    > >> listed in the class definition.

    >
    > >>> Is there any special rule for member objects as far as
    > >>> initialization of virtual base classes are concerned?

    >
    > >> The C++ standard explicitly states what is happening in your example
    > >> in 12.6.2/6:

    >
    > >> "All sub-objects representing virtual base classes are initialized by
    > >> the constructor of the most derived class (1.8). If the constructor
    > >> of the most derived class does not specify a mem-initializer for a
    > >> virtual base class V, then V's default constructor is called to
    > >> initialize the virtual base class subobject."

    >
    > >> And you *do* supply a mem-initializer for the virtual bases of C for
    > >> the C(int) constructor, so those are used when you create your B
    > >> object in main() because B uses the C(int) constructor for its c_obj
    > >> data member.

    >
    > >> --

    >
    > > Ok, so this is standard for member objects but not for base class
    > > constructors, like C(5)
    > > doesn't invoke E(5) and D(5) instead calls the default constructor of
    > > D and E... but why is this so?

    >
    > Why should it be NOT so? How should the compiler know that you
    > intend to pass the 5 along to the base classes and not 5*rand() ?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    well, thats where i'm confused with the initial output of the program
    which prints

    E
    D

    and not

    E is 5
    D is 5

    I hope my doubt over here is clear...
     
    Rahul, Dec 19, 2007
    #5
  6. Rahul wrote:
    > On Dec 19, 8:51 pm, "Victor Bazarov" <> wrote:
    >> Rahul wrote:
    >>> On Dec 19, 5:20 pm, Craig Scott <> wrote:
    >>>> On Dec 19, 10:43 pm, Rahul <> wrote:

    >>
    >>>>> Hi Everyone,

    >>
    >>>>> I was trying to understand the constructor order execution and i
    >>>>> tried the following example,

    >>
    >>>>> #include <stdio.h>

    >>
    >>>>> class A
    >>>>> {
    >>>>> public: A()
    >>>>> {
    >>>>> printf("A\n");
    >>>>> }

    >>
    >>>>> };

    >>
    >>>>> class D
    >>>>> {
    >>>>> public : D()
    >>>>> {
    >>>>> printf("D\n");
    >>>>> }
    >>>>> D(int i)
    >>>>> {
    >>>>> printf("D is %d\n",i);
    >>>>> }

    >>
    >>>>> };

    >>
    >>>>> class E
    >>>>> {
    >>>>> public: E()
    >>>>> {
    >>>>> printf("E\n");
    >>>>> }
    >>>>> E(int i)
    >>>>> {
    >>>>> printf("E is %d\n",i);
    >>>>> }

    >>
    >>>>> };

    >>
    >>>>> class C : virtual public E, virtual public D
    >>>>> {
    >>>>> public: C()
    >>>>> {
    >>>>> printf("C\n");
    >>>>> }
    >>>>> C(int a) : D(a), E(a)
    >>>>> {
    >>>>> printf("C is %d\n",a);
    >>>>> }

    >>
    >>>>> };

    >>
    >>>>> class B : public A, public C
    >>>>> {
    >>>>> C c_obj;
    >>>>> public: B() : C(5), c_obj(10)
    >>>>> {
    >>>>> printf("B\n");
    >>>>> }

    >>
    >>>>> };

    >>
    >>>>> int main()
    >>>>> {
    >>>>> B obj;
    >>>>> return (0);

    >>
    >>>>> }

    >>
    >>>>> I get the following output,

    >>
    >>>>> E // virtual base (left to right)
    >>>>> D // virtual base (left to right)
    >>>>> A // base class
    >>>>> C is 5 // base class
    >>>>> E is 10 // member object
    >>>>> D is 10 // member object
    >>>>> C is 10 // member object
    >>>>> B // constructor

    >>
    >>>>> Yes, the virtual base class constructors (default) are invoked
    >>>>> first for obj as expected.
    >>>>> However, for the member object c_obj, the virtual base class
    >>>>> constructors aren't invoked ( i mean the default constructor of E
    >>>>> and D) instead the second version ( accepting an integer ) is
    >>>>> called?

    >>
    >>>> Why should the default constructors be called? You specify the non-
    >>>> default constructors in your initialization list, so those will be
    >>>> used. As you correctly observe, virtual base classes are
    >>>> initialized before all other base classes and this is done in the
    >>>> order they are listed in the class definition.

    >>
    >>>>> Is there any special rule for member objects as far as
    >>>>> initialization of virtual base classes are concerned?

    >>
    >>>> The C++ standard explicitly states what is happening in your
    >>>> example in 12.6.2/6:

    >>
    >>>> "All sub-objects representing virtual base classes are initialized
    >>>> by the constructor of the most derived class (1.8). If the
    >>>> constructor of the most derived class does not specify a
    >>>> mem-initializer for a virtual base class V, then V's default
    >>>> constructor is called to initialize the virtual base class
    >>>> subobject."

    >>
    >>>> And you *do* supply a mem-initializer for the virtual bases of C
    >>>> for the C(int) constructor, so those are used when you create your
    >>>> B object in main() because B uses the C(int) constructor for its
    >>>> c_obj data member.

    >>
    >>>> --

    >>
    >>> Ok, so this is standard for member objects but not for base class
    >>> constructors, like C(5)
    >>> doesn't invoke E(5) and D(5) instead calls the default constructor
    >>> of D and E... but why is this so?

    >>
    >> Why should it be NOT so? How should the compiler know that you
    >> intend to pass the 5 along to the base classes and not 5*rand() ?
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    > well, thats where i'm confused with the initial output of the program
    > which prints
    >
    > E
    > D
    >
    > and not
    >
    > E is 5
    > D is 5
    >
    > I hope my doubt over here is clear...


    I think you're missing the simple fact that virtual base class subobjects
    are constructed by the most derived class' constructor. If you don't put
    virtual base class initialisers in _that_ initialiser list, the default
    constructor is used. Is there anything unclear about this particular rule?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Dec 19, 2007
    #6
  7. Rahul

    Rahul Guest

    On Dec 19, 9:07 pm, "Victor Bazarov" <> wrote:
    > Rahul wrote:
    > > On Dec 19, 8:51 pm, "Victor Bazarov" <> wrote:
    > >> Rahul wrote:
    > >>> On Dec 19, 5:20 pm, Craig Scott <> wrote:
    > >>>> On Dec 19, 10:43 pm, Rahul <> wrote:

    >
    > >>>>> Hi Everyone,

    >
    > >>>>> I was trying to understand the constructor order execution and i
    > >>>>> tried the following example,

    >
    > >>>>> #include <stdio.h>

    >
    > >>>>> class A
    > >>>>> {
    > >>>>> public: A()
    > >>>>> {
    > >>>>> printf("A\n");
    > >>>>> }

    >
    > >>>>> };

    >
    > >>>>> class D
    > >>>>> {
    > >>>>> public : D()
    > >>>>> {
    > >>>>> printf("D\n");
    > >>>>> }
    > >>>>> D(int i)
    > >>>>> {
    > >>>>> printf("D is %d\n",i);
    > >>>>> }

    >
    > >>>>> };

    >
    > >>>>> class E
    > >>>>> {
    > >>>>> public: E()
    > >>>>> {
    > >>>>> printf("E\n");
    > >>>>> }
    > >>>>> E(int i)
    > >>>>> {
    > >>>>> printf("E is %d\n",i);
    > >>>>> }

    >
    > >>>>> };

    >
    > >>>>> class C : virtual public E, virtual public D
    > >>>>> {
    > >>>>> public: C()
    > >>>>> {
    > >>>>> printf("C\n");
    > >>>>> }
    > >>>>> C(int a) : D(a), E(a)
    > >>>>> {
    > >>>>> printf("C is %d\n",a);
    > >>>>> }

    >
    > >>>>> };

    >
    > >>>>> class B : public A, public C
    > >>>>> {
    > >>>>> C c_obj;
    > >>>>> public: B() : C(5), c_obj(10)
    > >>>>> {
    > >>>>> printf("B\n");
    > >>>>> }

    >
    > >>>>> };

    >
    > >>>>> int main()
    > >>>>> {
    > >>>>> B obj;
    > >>>>> return (0);

    >
    > >>>>> }

    >
    > >>>>> I get the following output,

    >
    > >>>>> E // virtual base (left to right)
    > >>>>> D // virtual base (left to right)
    > >>>>> A // base class
    > >>>>> C is 5 // base class
    > >>>>> E is 10 // member object
    > >>>>> D is 10 // member object
    > >>>>> C is 10 // member object
    > >>>>> B // constructor

    >
    > >>>>> Yes, the virtual base class constructors (default) are invoked
    > >>>>> first for obj as expected.
    > >>>>> However, for the member object c_obj, the virtual base class
    > >>>>> constructors aren't invoked ( i mean the default constructor of E
    > >>>>> and D) instead the second version ( accepting an integer ) is
    > >>>>> called?

    >
    > >>>> Why should the default constructors be called? You specify the non-
    > >>>> default constructors in your initialization list, so those will be
    > >>>> used. As you correctly observe, virtual base classes are
    > >>>> initialized before all other base classes and this is done in the
    > >>>> order they are listed in the class definition.

    >
    > >>>>> Is there any special rule for member objects as far as
    > >>>>> initialization of virtual base classes are concerned?

    >
    > >>>> The C++ standard explicitly states what is happening in your
    > >>>> example in 12.6.2/6:

    >
    > >>>> "All sub-objects representing virtual base classes are initialized
    > >>>> by the constructor of the most derived class (1.8). If the
    > >>>> constructor of the most derived class does not specify a
    > >>>> mem-initializer for a virtual base class V, then V's default
    > >>>> constructor is called to initialize the virtual base class
    > >>>> subobject."

    >
    > >>>> And you *do* supply a mem-initializer for the virtual bases of C
    > >>>> for the C(int) constructor, so those are used when you create your
    > >>>> B object in main() because B uses the C(int) constructor for its
    > >>>> c_obj data member.

    >
    > >>>> --

    >
    > >>> Ok, so this is standard for member objects but not for base class
    > >>> constructors, like C(5)
    > >>> doesn't invoke E(5) and D(5) instead calls the default constructor
    > >>> of D and E... but why is this so?

    >
    > >> Why should it be NOT so? How should the compiler know that you
    > >> intend to pass the 5 along to the base classes and not 5*rand() ?

    >
    > >> V
    > >> --
    > >> Please remove capital 'A's when replying by e-mail
    > >> I do not respond to top-posted replies, please don't ask

    >
    > > well, thats where i'm confused with the initial output of the program
    > > which prints

    >
    > > E
    > > D

    >
    > > and not

    >
    > > E is 5
    > > D is 5

    >
    > > I hope my doubt over here is clear...

    >
    > I think you're missing the simple fact that virtual base class subobjects
    > are constructed by the most derived class' constructor. If you don't put
    > virtual base class initialisers in _that_ initialiser list, the default
    > constructor is used. Is there anything unclear about this particular rule?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    I'm afraid that doesn't help, could you illustrate with a simple
    example...
    And moreover, i didn't get the reason as why virtual bases have to be
    initialized first...
    may be i need to know that...
     
    Rahul, Dec 19, 2007
    #7
  8. Rahul wrote:
    >> [..]
    >> I think you're missing the simple fact that virtual base class
    >> subobjects are constructed by the most derived class' constructor.
    >> If you don't put virtual base class initialisers in _that_
    >> initialiser list, the default constructor is used. Is there
    >> anything unclear about this particular rule?
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    > I'm afraid that doesn't help, could you illustrate with a simple
    > example...
    > And moreover, i didn't get the reason as why virtual bases have to be
    > initialized first...
    > may be i need to know that...


    Here is what you are seeing:

    struct A {
    int a;
    A() : a(42) {}
    A(int a_) : a(a_) {}
    };

    struct B : virtual A {
    B() : A(666) {} // initialises 'A' using A::A(int)
    };

    struct C : B {
    C() {} // initialises 'A' using A::A()
    };

    #include <iostream>
    #include <ostream>
    int main() {
    B b;
    C c;
    std::cout << "b.a = " << b.a << std::endl;
    std::cout << "c.a = " << c.a << std::endl;
    }

    The reason the virtual base class is constructed in the most derived
    object's initialiser list is because with every object there will be
    only one instance of it if more than one base class derives from it
    virtually. Here is another example:


    struct A {
    int a;
    A() : a(42) {}
    A(int a_) : a(a_) {}
    };

    struct B1 : virtual A {
    B1() : A(666) {} // initialises 'A' using A::A(int)
    };

    struct B2 : virtual A {
    B2() : A(777) {} // initialises 'A' using A::A(int)
    };

    struct C : B1, B2 {
    C() {} // initialises 'A' using A::A()
    };

    #include <iostream>
    #include <ostream>
    int main() {
    B1 b1;
    B2 b2;
    C c;
    std::cout << "b1.a = " << b1.a << std::endl;
    std::cout << "b2.a = " << b2.a << std::endl;
    std::cout << "c.a = " << c.a << std::endl;
    }

    Since in a 'C' instance there is only one instance of 'A', that
    subobject has to be constructed only once during the construction
    of a single 'C' object. Both 'B1' and 'B2' (and possibly more)
    initialise "their" 'A' subobjects according to how they want.
    The compiler cannot pick which initialiser from those provided
    by 'Bx' classes to use. The only logical place, then, is to
    require that the _common_ 'A' is initialised by the 'C's c-tor.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Dec 19, 2007
    #8
  9. Rahul

    Joe Greer Guest

    Rahul <> wrote in
    news::

    > I'm afraid that doesn't help, could you illustrate with a simple
    > example...
    > And moreover, i didn't get the reason as why virtual bases have to be
    > initialized first...
    > may be i need to know that...
    >


    In C++, the rule is that until a constructor has successfully completed,
    you don't have an object. This is true during construction as well. If
    a derived class is going to be able to make use of methods or variables
    from a parent class, then they must have been constructed first. Thus,
    the construction order always goes from parent to child and the
    destruction order always goes from child to parent.

    By default, the default constructor is used when creating any object.
    If you want a different constructor to be used, you must specify the
    constructor with the parameters you want to use. For example:

    E e;

    would initialize e with the default constructor whereas:

    E e(5);

    would invoke the constructor which takes an int (ignoring implicit casts
    for now).

    For simple objects, you specify the constructor by giving a parameter
    list to the variable name. With constructors, you specify the
    constructor by giving the class name followed by the parameter list in
    the deriveds constructor. For example:

    class B {
    public:
    B(int b) : m_B(b) {}
    private:
    int m_B;
    };

    class D : public B
    {
    public:
    D(int d) : B(d) {}
    };

    Hope that helps some,

    joe
     
    Joe Greer, Dec 19, 2007
    #9
  10. Rahul

    Rahul Guest

    On Dec 19, 9:34 pm, "Victor Bazarov" <> wrote:
    > Rahul wrote:
    > >> [..]
    > >> I think you're missing the simple fact that virtual base class
    > >> subobjects are constructed by the most derived class' constructor.
    > >> If you don't put virtual base class initialisers in _that_
    > >> initialiser list, the default constructor is used. Is there
    > >> anything unclear about this particular rule?

    >
    > >> V
    > >> --
    > >> Please remove capital 'A's when replying by e-mail
    > >> I do not respond to top-posted replies, please don't ask

    >
    > > I'm afraid that doesn't help, could you illustrate with a simple
    > > example...
    > > And moreover, i didn't get the reason as why virtual bases have to be
    > > initialized first...
    > > may be i need to know that...

    >
    > Here is what you are seeing:
    >
    > struct A {
    > int a;
    > A() : a(42) {}
    > A(int a_) : a(a_) {}
    > };
    >
    > struct B : virtual A {
    > B() : A(666) {} // initialises 'A' using A::A(int)
    > };
    >
    > struct C : B {
    > C() {} // initialises 'A' using A::A()
    > };
    >
    > #include <iostream>
    > #include <ostream>
    > int main() {
    > B b;
    > C c;
    > std::cout << "b.a = " << b.a << std::endl;
    > std::cout << "c.a = " << c.a << std::endl;
    > }
    >
    > The reason the virtual base class is constructed in the most derived
    > object's initialiser list is because with every object there will be
    > only one instance of it if more than one base class derives from it
    > virtually. Here is another example:
    >
    > struct A {
    > int a;
    > A() : a(42) {}
    > A(int a_) : a(a_) {}
    > };
    >
    > struct B1 : virtual A {
    > B1() : A(666) {} // initialises 'A' using A::A(int)
    > };
    >
    > struct B2 : virtual A {
    > B2() : A(777) {} // initialises 'A' using A::A(int)
    > };
    >
    > struct C : B1, B2 {
    > C() {} // initialises 'A' using A::A()
    > };
    >
    > #include <iostream>
    > #include <ostream>
    > int main() {
    > B1 b1;
    > B2 b2;
    > C c;
    > std::cout << "b1.a = " << b1.a << std::endl;
    > std::cout << "b2.a = " << b2.a << std::endl;
    > std::cout << "c.a = " << c.a << std::endl;
    > }
    >
    > Since in a 'C' instance there is only one instance of 'A', that
    > subobject has to be constructed only once during the construction
    > of a single 'C' object. Both 'B1' and 'B2' (and possibly more)
    > initialise "their" 'A' subobjects according to how they want.
    > The compiler cannot pick which initialiser from those provided
    > by 'Bx' classes to use. The only logical place, then, is to
    > require that the _common_ 'A' is initialised by the 'C's c-tor.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    Thanks victor for the examples, thats puts things in perspective...
     
    Rahul, Dec 19, 2007
    #10
  11. Rahul

    James Kanze Guest

    On Dec 19, 5:18 pm, Rahul <> wrote:

    [...]
    > And moreover, i didn't get the reason as why virtual bases
    > have to be initialized first...


    Who should initialize it?

    In your precise example, one could argue that C should, since
    it's not explicitly known any higher. But what happens then if
    you derived from B:

    class F : public B, public virtual E

    ? One could imagine a rule in which the compiler constructed
    the inheritance graph, and then initialized the virtual base in
    the highest node which included all possible paths to it, but
    this would be considerably more complicated, both to implement
    and to understand, since it would result in different virtual
    bases being initialized in different classes in the hierarchy.
    (In the above example, for example, E would be initialized by F,
    but D would still be initialized by C. And what does it buy us?
    In practice, virtual base classes are almost always empty, and
    only have default constructors (since they have no data to
    initialize).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Dec 20, 2007
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. priya
    Replies:
    0
    Views:
    1,246
    priya
    Oct 3, 2005
  2. =?Utf-8?B?QmlsbCBCb3Jn?=

    Execution order of PageLoad for user controls

    =?Utf-8?B?QmlsbCBCb3Jn?=, Mar 6, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    3,385
    =?Utf-8?B?QmlsbCBCb3Jn?=
    Mar 6, 2004
  3. Bijoy Naick

    Execution order of Validation Controls

    Bijoy Naick, Jun 8, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    2,979
    Martin Marinov
    Jun 8, 2004
  4. Replies:
    3
    Views:
    833
    Michael Rasmussen
    Mar 30, 2006
  5. Generic Usenet Account
    Replies:
    10
    Views:
    2,321
Loading...

Share This Page