constructor initialization list

Discussion in 'C++' started by Makis Papapanagiotou, Nov 3, 2004.

  1. Hello all,

    There is a strange case where a class Test is composed from three objects of
    other classes. i.e.

    class Test
    { public:
    Test();
    private:
    Point x;
    Cat y;
    Dog z;
    };

    where the classes Point, Cat, Dog are

    class Point
    { public:
    Point();
    Point(Point& x, Dog& y);
    private:
    };

    class Cat
    { public:
    Cat();
    Cat(Point& x, Dog& y);
    private:
    };

    class Dog
    { public:
    Dog();
    Dog(Point& x, Cat& y);
    private:
    };

    If we were calling the default constructors they is no problem, since as
    STROUSTRUP is wrtiing in his book they are called in the order they are
    defined in the class the main class (Test).

    My big problem is why the following is working? i.e when the other
    constructors are called.

    Test::Test():x(), y(x,z), z(x,y)

    since the creation of object "y" is related with the creation of object "z".

    Can any body give an explanation of this strange behaviour?

    Thanks in advance,
     
    Makis Papapanagiotou, Nov 3, 2004
    #1
    1. Advertising

  2. Makis Papapanagiotou

    JKop Guest


    > Can any body give an explanation of this strange behaviour?



    The objects are contructed in the order in which they are, in the
    Initialization List.

    For objects that *aren't* listed in the initialization list, they are
    constructed *before* all other member objects. So, given the following:


    #include <string>

    class Blah
    {
    public:
    std::string a;
    std::string b;
    std::string c;
    std::string d;
    std::string e;
    std::string f;

    Blah() : c("Monkey!"), e(), a(), f("Ape!");
    };


    The order of in which the member objects are consructed in the above is as
    follows:

    b
    d
    c
    e
    a
    f


    -JKop
     
    JKop, Nov 3, 2004
    #2
    1. Advertising

  3. Makis Papapanagiotou

    JKop Guest


    > Test::Test():x(), y(x,z), z(x,y)



    Opps! I missed the point with my last post.


    The above code is ill-formed.


    -JKop
     
    JKop, Nov 3, 2004
    #3
  4. Makis Papapanagiotou wrote:
    >
    > Hello all,
    >
    > There is a strange case where a class Test is composed from three objects of
    > other classes. i.e.
    >
    > class Test
    > { public:
    > Test();
    > private:
    > Point x;
    > Cat y;
    > Dog z;
    > };
    >
    > where the classes Point, Cat, Dog are
    >
    > class Point
    > { public:
    > Point();
    > Point(Point& x, Dog& y);
    > private:
    > };
    >
    > class Cat
    > { public:
    > Cat();
    > Cat(Point& x, Dog& y);
    > private:
    > };
    >
    > class Dog
    > { public:
    > Dog();
    > Dog(Point& x, Cat& y);
    > private:
    > };
    >
    > If we were calling the default constructors they is no problem, since as
    > STROUSTRUP is wrtiing in his book they are called in the order they are
    > defined in the class the main class (Test).
    >
    > My big problem is why the following is working?


    Define 'working'

    > i.e when the other
    > constructors are called.


    It is still the same order:
    x gets constructed first
    y gets constructed next
    z gets constructed last

    >
    > Test::Test():x(), y(x,z), z(x,y)


    The order in which constructors of member objects are called
    is entirely defined by the order in which they are listed
    in the class declaration. Here, in the initializer list
    you simply specify *which* constructor to use for the members,
    not the order in which they are called.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Nov 3, 2004
    #4
  5. JKop wrote:
    >
    > > Can any body give an explanation of this strange behaviour?

    >
    > The objects are contructed in the order in which they are, in the
    > Initialization List.


    You might want to reread on this.
    The order is defined entirely by the order the members are listed
    in the class declaration. The initialzation list just selects which
    constructor to use, but does not change the order in which members
    get initialized.


    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Nov 3, 2004
    #5
  6. Hello,

    Sorry but this is not covering my question since in your example the objects
    are not related to each other.

    In my case they are

    Test:: x( ), y(x,z), z(x,y)

    So the object "y" in order to be constructed needs the object "z", but "z"
    in order to be constructed needs "y" first.
    Even though they are constructed.

    Hence how this is done? Because it is done and it is not an error !!!


    Thanks,

    "JKop" <> wrote in message
    news:Xn5id.40762$...
    >
    > > Can any body give an explanation of this strange behaviour?

    >
    >
    > The objects are contructed in the order in which they are, in the
    > Initialization List.
    >
    > For objects that *aren't* listed in the initialization list, they are
    > constructed *before* all other member objects. So, given the following:
    >
    >
    > #include <string>
    >
    > class Blah
    > {
    > public:
    > std::string a;
    > std::string b;
    > std::string c;
    > std::string d;
    > std::string e;
    > std::string f;
    >
    > Blah() : c("Monkey!"), e(), a(), f("Ape!");
    > };
    >
    >
    > The order of in which the member objects are consructed in the above is as
    > follows:
    >
    > b
    > d
    > c
    > e
    > a
    > f
    >
    >
    > -JKop
    >
    >
     
    Makis Papapanagiotou, Nov 3, 2004
    #6
  7. Makis Papapanagiotou

    JKop Guest

    Karl Heinz Buchegger posted:

    > JKop wrote:
    >>
    >> > Can any body give an explanation of this strange behaviour?

    >>
    >> The objects are contructed in the order in which they are, in the
    >> Initialization List.

    >
    > You might want to reread on this.
    > The order is defined entirely by the order the members are listed
    > in the class declaration. The initialzation list just selects which
    > constructor to use, but does not change the order in which members
    > get initialized.



    I'm wrong!


    I wasn't exactly sure so I went off and tested it, but then I realized
    that my "test" would have produced the same results either way.

    So... in summation:

    Objects are constructed in the order in which they appear in the class
    declaration.

    (I think what had me confused is where you have multiple base classes
    and you use the initialization list to specify the order in which the
    base classes' constructors are called.)


    -JKop
     
    JKop, Nov 3, 2004
    #7
  8. Makis Papapanagiotou wrote:
    >
    > Hello,
    >
    > Sorry but this is not covering my question since in your example the objects
    > are not related to each other.
    >
    > In my case they are
    >
    > Test:: x( ), y(x,z), z(x,y)
    >
    > So the object "y" in order to be constructed needs the object "z", but "z"
    > in order to be constructed needs "y" first.
    > Even though they are constructed.
    >
    > Hence how this is done? Because it is done and it is not an error !!


    It all depends on what the Cat or Dog constructor do with
    the passed reference.

    When the Cat constructor is called and passed the Dog object,
    the Dog object isn't yet fully constructed, but the memory for
    that object has already been reserved. So for the Cat object it
    is safe to eg. store a pointer to the Dog object or create a reference
    to it. You, the programmer, know that at exactly this memory location
    eventually there will be a fully constructed Dog object, when the
    whole initialization is completed.


    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Nov 3, 2004
    #8
  9. Hello,

    Yes it is still in the same order:

    x gets constructed first
    y gets constructed next
    z gets constructed last

    At least thats what we see if we put a "cout" stetement in the
    constructors...

    Thanks,

    "Karl Heinz Buchegger" <> wrote in message
    news:...
    > Makis Papapanagiotou wrote:
    > >
    > > Hello all,
    > >
    > > There is a strange case where a class Test is composed from three

    objects of
    > > other classes. i.e.
    > >
    > > class Test
    > > { public:
    > > Test();
    > > private:
    > > Point x;
    > > Cat y;
    > > Dog z;
    > > };
    > >
    > > where the classes Point, Cat, Dog are
    > >
    > > class Point
    > > { public:
    > > Point();
    > > Point(Point& x, Dog& y);
    > > private:
    > > };
    > >
    > > class Cat
    > > { public:
    > > Cat();
    > > Cat(Point& x, Dog& y);
    > > private:
    > > };
    > >
    > > class Dog
    > > { public:
    > > Dog();
    > > Dog(Point& x, Cat& y);
    > > private:
    > > };
    > >
    > > If we were calling the default constructors they is no problem, since as
    > > STROUSTRUP is wrtiing in his book they are called in the order they are
    > > defined in the class the main class (Test).
    > >
    > > My big problem is why the following is working?

    >
    > Define 'working'
    >
    > > i.e when the other
    > > constructors are called.

    >
    > It is still the same order:
    > x gets constructed first
    > y gets constructed next
    > z gets constructed last
    >
    > >
    > > Test::Test():x(), y(x,z), z(x,y)

    >
    > The order in which constructors of member objects are called
    > is entirely defined by the order in which they are listed
    > in the class declaration. Here, in the initializer list
    > you simply specify *which* constructor to use for the members,
    > not the order in which they are called.
    >
    > --
    > Karl Heinz Buchegger
    >
     
    Makis Papapanagiotou, Nov 3, 2004
    #9
  10. Makis Papapanagiotou

    JKop Guest

    JKop posted:

    >
    >> Test::Test():x(), y(x,z), z(x,y)

    >
    >
    > Opps! I missed the point with my last post.
    >
    >
    > The above code is ill-formed.
    >
    >
    > -JKop



    Again I'm wrong!
     
    JKop, Nov 3, 2004
    #10
  11. Makis Papapanagiotou wrote:
    >
    > Hello,
    >
    > Yes it is still in the same order:
    >
    > x gets constructed first
    > y gets constructed next
    > z gets constructed last
    >
    > At least thats what we see if we put a "cout" stetement in the
    > constructors...


    Well. I got your question wrong, mostly because you didn't ask
    a specific question other then: "Why is this <lots of code> not wrong?"
    Moral of story: If you want to emphasize on something, code is a good
    thing, but tell us exactly what is puzzeling you.

    See my other reply for some explanations.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Nov 3, 2004
    #11
  12. Makis Papapanagiotou

    Jeff Flinn Guest

    "JKop" <> wrote in message
    news:CB5id.40764$...
    > Karl Heinz Buchegger posted:
    >
    > > JKop wrote:
    > >>
    > >> > Can any body give an explanation of this strange behaviour?
    > >>
    > >> The objects are contructed in the order in which they are, in the
    > >> Initialization List.

    > >
    > > You might want to reread on this.
    > > The order is defined entirely by the order the members are listed
    > > in the class declaration. The initialzation list just selects which
    > > constructor to use, but does not change the order in which members
    > > get initialized.

    >
    >
    > I'm wrong!
    >
    >
    > I wasn't exactly sure so I went off and tested it, but then I realized
    > that my "test" would have produced the same results either way.
    >
    > So... in summation:
    >
    > Objects are constructed in the order in which they appear in the class
    > declaration.
    >
    > (I think what had me confused is where you have multiple base classes
    > and you use the initialization list to specify the order in which the
    > base classes' constructors are called.)


    Wrong again.

    Jeff F
     
    Jeff Flinn, Nov 3, 2004
    #12
  13. JKop wrote:
    >>Can any body give an explanation of this strange behaviour?

    >
    >
    >
    > The objects are contructed in the order in which they are, in the
    > Initialization List.



    I don't think that's right. The order of member construction is the
    order in which they are defined in the class. The order of member
    destruction is the reverse order in which they are defined in the class,
    regardless of the order of the initializer list. Inherited classes are
    constructed before members in the order in which they are inherited and
    destructed in reverse order of construction.

    #include <iostream>

    template <int num>
    class Yell
    {
    public:
    int m_num;

    Yell()
    : m_num()
    {
    std::cout << num << " Default" << std::endl;
    }

    Yell( int i )
    : m_num( i )
    {
    std::cout << num << " Nondefault( " << i << " )" << std::endl;
    }

    ~Yell()
    {
    std::cout << num << " DESTRUCT( " << m_num << " )" << std::endl;
    }

    };

    class Blah
    : public Yell<10>, public Yell<11>
    {
    public:
    Yell<1> a;
    Yell<2> b;
    Yell<3> c;
    Yell<4> d;
    Yell<5> e;
    Yell<6> f;

    Blah() : c(100), e(), a(), f(200), Yell<11>( 300 )
    {
    }
    };

    int main()
    {
    Blah x;
    }

    output:

    10 Default
    11 Nondefault( 300 )
    1 Default
    2 Default
    3 Nondefault( 100 )
    4 Default
    5 Default
    6 Nondefault( 200 )
    6 DESTRUCT( 200 )
    5 DESTRUCT( 0 )
    4 DESTRUCT( 0 )
    3 DESTRUCT( 100 )
    2 DESTRUCT( 0 )
    1 DESTRUCT( 0 )
    11 DESTRUCT( 300 )
    10 DESTRUCT( 0 )
     
    Gianni Mariani, Nov 3, 2004
    #13
  14. Makis Papapanagiotou

    Ron Natalie Guest

    JKop wrote:
    >>Can any body give an explanation of this strange behaviour?

    >
    >
    >
    > The objects are contructed in the order in which they are, in the
    > Initialization List.
    >
    > For objects that *aren't* listed in the initialization list, they are
    > constructed *before* all other member objects. So, given the following:


    It doesn't matter whether they are listed or NOT.
    The initilization list has NO BEARING on the order of connstruction.
     
    Ron Natalie, Nov 3, 2004
    #14
  15. Makis Papapanagiotou

    Chris Theis Guest

    "JKop" <> wrote in message
    news:CB5id.40764$...
    > Karl Heinz Buchegger posted:
    >
    > > JKop wrote:
    > >>
    > >> > Can any body give an explanation of this strange behaviour?
    > >>
    > >> The objects are contructed in the order in which they are, in the
    > >> Initialization List.

    > >
    > > You might want to reread on this.
    > > The order is defined entirely by the order the members are listed
    > > in the class declaration. The initialzation list just selects which
    > > constructor to use, but does not change the order in which members
    > > get initialized.

    >
    >
    > I'm wrong!
    >
    >
    > I wasn't exactly sure so I went off and tested it, but then I realized
    > that my "test" would have produced the same results either way.
    >
    > So... in summation:
    >
    > Objects are constructed in the order in which they appear in the class
    > declaration.
    >
    > (I think what had me confused is where you have multiple base classes
    > and you use the initialization list to specify the order in which the
    > base classes' constructors are called.)
    >


    Sorry to tell you, but you´re wrong again. The initialization list does not
    specify the order of execution of the base class ctors. To make a long
    matter short - read the FAQ, item 25.14.

    Chris
     
    Chris Theis, Nov 3, 2004
    #15
  16. Makis Papapanagiotou

    DaKoadMunky Guest

    >The objects are contructed in the order in which they are, in the
    >Initialization List.
    >
    >For objects that *aren't* listed in the initialization list, they are
    >constructed *before* all other member objects.


    This is absolutely false.

    Why would you think this?

    How can you expect people to take your claim of being an expert level C++
    programmer seriously when you can get something like this so wrong?
     
    DaKoadMunky, Nov 4, 2004
    #16
  17. Makis Papapanagiotou

    JKop Guest

    DaKoadMunky posted:

    >>The objects are contructed in the order in which they are, in the
    >>Initialization List.
    >>
    >>For objects that *aren't* listed in the initialization list, they are
    >>constructed *before* all other member objects.

    >
    > This is absolutely false.
    >
    > Why would you think this?
    >
    > How can you expect people to take your claim of being an expert level C++
    > programmer seriously when you can get something like this so wrong?



    I consider it to be one of those aspects which I wouldn't really pay much
    attention to, until a scenrio comes up where I need to, at which point I'll
    consult a reference.

    For example, I know how "const" works with pointers, ie.:

    const char* p_blah;

    The variable "p_blah" is *not* const, but what it points to *is*.


    char* const p_blah;

    The variable "p_blah" is const, but what it points to is *not*.


    So anyway, I've got that well and trully asimiliated.

    But then when it comes to pointers to pointers, I'm not sure how the whole
    const system works there. I haven't needed to use it thus far, so I haven't
    read up on it. When and if the time comes that I need to use it, I will
    *not* guess (similarly with the constructor order scenario), I will consult
    a reference.

    If I were to learn everything about everything all at once, then it would
    take me a very long time to get proficient, sort of like how when learning
    to drive, you don't spend a few hours messing with the clutch, then spend a
    few hours driving. Instead you go out and do them both together and
    eventually they'll come together.


    So in summation, while I was wrong, still if there were a scenario in which
    constructor order was important, I would've definitely consulted a
    reference.

    I say "consult a reference"; which I would like to mean the C++ Standard...
    but for Christ's sake the thing is just too God damn long!


    So anyway, yes I was wrong; but in my defense, if it were really that
    important, I would've sought clarity.


    -JKop
     
    JKop, Nov 4, 2004
    #17
  18. Makis Papapanagiotou

    DaKoadMunky Guest

    >I consider it to be one of those aspects which I wouldn't really pay much
    >attention to, until a scenrio comes up where I need to, at which point I'll
    >consult a reference.


    > When and if the time comes that I need to use it, I will
    >*not* guess (similarly with the constructor order scenario), I will consult
    >a reference.


    So you are saying that you did not use any reference materials to learn how the
    order of items in a base/member initializer list impacted execution order of
    those initializers?

    That is okay. We can't know everything. I have been using C++ for almost a
    decade and I can tell you almost nothing about I/O using streams. I just have
    not needed them. I really don't know what the keyword volatile is for either.

    The things I do know I have learned either out of curiousity because I thought
    they might be important or because I was fortunate enough to have been exposed
    to those things via study of books and magazines.

    I would like to know though why you think you had the knowledge required to
    make a definitive statement regarding how the order of items in a base/member
    initializer list impacted execution order of those initializers.

    Did somebody teach you? Okay then. That happens. Sadly I have seen C++ books
    on the store shelves that contained erroneous information. Some of the C++
    "tips" at www.devx.com are simply horrendous. One of them I just read led to
    undefined behavior and even if it didn't lead to undefined behavior it had no
    value, but there it was posted as a "tip."

    Did you base your statements on observed behavior? For shame. Just because a
    compiler accepts a statement and then executes it in a certain way does not
    mean it is correct. The only authority is the Standard (which I keep meaning
    to get...honest...I am poor...please send me $65 for the hardback version...I
    hate reading on the monitor)

    Were your statements based on how you think the initializer list should work?

    Just curious.
     
    DaKoadMunky, Nov 5, 2004
    #18
  19. Makis Papapanagiotou

    JKop Guest

    DaKoadMunky posted:

    >>I consider it to be one of those aspects which I wouldn't really pay
    >>much attention to, until a scenrio comes up where I need to, at which
    >>point I'll consult a reference.

    >
    >> When and if the time comes that I need to use it, I will
    >>*not* guess (similarly with the constructor order scenario), I will
    >>consult a reference.

    >
    > So you are saying that you did not use any reference materials to learn
    > how the order of items in a base/member initializer list impacted
    > execution order of those initializers?



    Correct.


    > That is okay. We can't know everything. I have been using C++ for
    > almost a decade and I can tell you almost nothing about I/O using
    > streams. I just have not needed them. I really don't know what the
    > keyword volatile is for either.
    >
    > The things I do know I have learned either out of curiousity because I
    > thought they might be important or because I was fortunate enough to
    > have been exposed to those things via study of books and magazines.
    >
    > I would like to know though why you think you had the knowledge
    > required to make a definitive statement regarding how the order of
    > items in a base/member initializer list impacted execution order of
    > those initializers.



    I tested it.

    For instance - if some-one said to me, "will this compile?", and I wasn't
    sure, then I wouldn't read the Standard, I'd try compile it.

    So I made up a little test program to see what order in which the
    contructors were invoked. The results suggested what I posted. But... then a
    couple of minutes later, I realized that either way the test would've given
    the same results.


    So I unintentionally posted misinformation.


    Now I know!


    > Did somebody teach you?



    Books.


    > Okay then. That happens. Sadly I have seen
    > C++ books on the store shelves that contained erroneous information.



    void main() {}


    > Some of the C++ "tips" at www.devx.com are simply horrendous. One of
    > them I just read led to undefined behavior and even if it didn't lead
    > to undefined behavior it had no value, but there it was posted as a
    > "tip."
    >
    > Did you base your statements on observed behavior? For shame. Just
    > because a compiler accepts a statement and then executes it in a
    > certain way does not mean it is correct. The only authority is the
    > Standard (which I keep meaning to get...honest...I am poor...please
    > send me $65 for the hardback version...I hate reading on the monitor)



    Yes, correct, the only authority is the Standard! One day I thought to
    myself, hmm... I'll just print it out and read it all. It might take a
    while, but hey!

    So I emailed it to some-one who worked in an office with a printer and he
    printed it out for me.

    The next day I was handed a doorstep.

    So, while I'd very much like to read through the entire C++ Standard and
    attain absolute clarity, life is too short! Such a vast amount of
    information is just a bit overwhelming to me.


    > Were your statements based on how you think the initializer list should
    > work?



    Partly I suppose. I probably didn't scrutanize my test results so closely
    because they were showing me what I wanted to see. (Sort of like how when I
    think I've lost something really important, I check all my other pockets
    before I check the one I thought I had it in. Sure it would've been logical
    to check the most likely location first, but in anxiety I compusively delay
    my misery).


    -JKop
     
    JKop, Nov 5, 2004
    #19
    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. Replies:
    6
    Views:
    465
    Ron Natalie
    Dec 11, 2005
  2. toton
    Replies:
    5
    Views:
    935
    Victor Bazarov
    Sep 28, 2006
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,248
  4. aaragon
    Replies:
    2
    Views:
    621
    James Kanze
    Nov 2, 2008
  5. balaji
    Replies:
    3
    Views:
    949
    Jens Thoms Toerring
    Aug 10, 2011
Loading...

Share This Page