Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > order of object initialization and the use of constructor initializer

Reply
Thread Tools

order of object initialization and the use of constructor initializer

 
 
Jess
Guest
Posts: n/a
 
      04-25-2007
Hello,

When I define default constructors, I tend to use constructor
initializers for member data. However, I was told the order in which
members are initialized is determined by the order of declaration in
the class, instead of the order they appear in the constructor
initializer. This would introduce interdependencies. Therefore, it
is safer to avoid such interdependence by assigning values to these
members inside the constructor body rather than initializing them in
the intializer. Could someone explain to me why this is the case?
Moreover, what kind of error could possibly happen due to the
"interdependency"?

Many thanks!

 
Reply With Quote
 
 
 
 
Gianni Mariani
Guest
Posts: n/a
 
      04-25-2007
Jess wrote:
> Hello,
>
> When I define default constructors, I tend to use constructor
> initializers for member data. However, I was told the order in which
> members are initialized is determined by the order of declaration in
> the class, instead of the order they appear in the constructor
> initializer. This would introduce interdependencies. Therefore, it
> is safer to avoid such interdependence by assigning values to these
> members inside the constructor body rather than initializing them in
> the intializer. Could someone explain to me why this is the case?
> Moreover, what kind of error could possibly happen due to the
> "interdependency"?


The order of construction is reversed for destruction. If you have
multiple constructors for the class, the order of construction is always
the same, as you said, no matter how the initializers are ordered.

Some compilers will issue a warning if the initializer list is not
consistent with the order of member declarations.

As for issues of interdependencies, I don't think I have ever come
across a situation where this was a problem.
 
Reply With Quote
 
 
 
 
Richard Herring
Guest
Posts: n/a
 
      04-26-2007
In message <. com>, Jess
<> writes
>Hello,
>
>When I define default constructors, I tend to use constructor
>initializers for member data. However, I was told the order in which
>members are initialized is determined by the order of declaration in
>the class, instead of the order they appear in the constructor
>initializer. This would introduce interdependencies. Therefore, it
>is safer to avoid such interdependence by assigning values to these
>members inside the constructor body rather than initializing them in
>the intializer.


They *still* get initialised in the order of declaration, but using the
default constructor (provided it exists).

And you have no choice, if the members don't have a default constructor,
or their assignment operator is not defined, or it has a different
effect from the constructor.

> Could someone explain to me why this is the case?
>Moreover, what kind of error could possibly happen due to the
>"interdependency"?
>
>Many thanks!
>


--
Richard Herring
 
Reply With Quote
 
Jess
Guest
Posts: n/a
 
      04-27-2007
If I have a class like:

class A{
int x;
int y;
string z;
B b;
A () : x(0), y(0) { x = 1;}
}

Then if I have a code that is "A a;" then I think the following
happens:
-- A() is called
-- x -> 0, y -> 0
-- z becomes null string
-- b is initialized by calling B's constructor
-- body of A() is entered, and x -> 1.

Is this right?
If A() is changed to:
A () : y(0), x(0) { x = 1;}

Then will the compiler complain? Thanks

Jess

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-27-2007
Jess wrote:
> If I have a class like:
>
> class A{
> int x;
> int y;
> string z;
> B b;
> A () : x(0), y(0) { x = 1;}
> }
>
> Then if I have a code that is "A a;" then I think the following
> happens:
> -- A() is called
> -- x -> 0, y -> 0
> -- z becomes null string


... because that's how the default string c-tor behaves.

> -- b is initialized by calling B's constructor


".. by calling B's _default_ constructor"

> -- body of A() is entered, and x -> 1.


1 -> x

>
> Is this right?


Pretty much.

> If A() is changed to:
> A () : y(0), x(0) { x = 1;}
>
> Then will the compiler complain? Thanks


I don't know, you need to ask the compiler.

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


 
Reply With Quote
 
=?iso-8859-1?q?Kirit_S=E6lensminde?=
Guest
Posts: n/a
 
      04-27-2007
On Apr 25, 12:07 pm, Jess <w...@hotmail.com> wrote:
> When I define default constructors, I tend to use constructor
> initializers for member data. However, I was told the order in which
> members are initialized is determined by the order of declaration in
> the class, instead of the order they appear in the constructor
> initializer. This would introduce interdependencies. Therefore, it
> is safer to avoid such interdependence by assigning values to these
> members inside the constructor body rather than initializing them in
> the intializer. Could someone explain to me why this is the case?
> Moreover, what kind of error could possibly happen due to the
> "interdependency"?


There are cases where one attribute needs to be passed into a
superclass constructor or into another attribute's constructor and
these can cause problems.

Where you're passing between attributes then you should order them
correctly in the class definition. Where you have to pass into the
superclass I've done something like this (heavily abridged):

// Super's constructor needs an int pointer to use
class Super { Super( int * ); };

// We store the int here
class Holder { int m_attribute; };

// We can now get the int constructed before Super needs it
class Sub : Holder, Super { Sub(); };

// Pass the int to Super
Sub::Sub()
: Holder(), Super( &m_attribute ) {}

As I understand it the order of the super-classes in the definition of
Sub is important, not the order of the calls in the definition of
Sub's constructor. This is analogous to the case with the attribute
order in the class definition.


K

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-27-2007
On Apr 27, 5:11 am, Jess <w...@hotmail.com> wrote:
> If I have a class like:


> class A{
> int x;
> int y;
> string z;
> B b;
> A () : x(0), y(0) { x = 1;}
> }


> Then if I have a code that is "A a;" then I think the following
> happens:
> -- A() is called
> -- x -> 0, y -> 0
> -- z becomes null string
> -- b is initialized by calling B's constructor
> -- body of A() is entered, and x -> 1.


> Is this right?
> If A() is changed to:
> A () : y(0), x(0) { x = 1;}


> Then will the compiler complain? Thanks


It might issue a warning, but the code is legal, and does
exactly what the previous code does.

The only time this is a problem is if you write something like:

A::A() : y( 0 ), x( y ) { x = 1; }

In this case, you actually have undefined behavior, because you
try to initialize x with y before having initialized y.

--
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

 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      04-27-2007
Jess <> wrote:
> When I define default constructors, I tend to use constructor
> initializers for member data. However, I was told the order in which
> members are initialized is determined by the order of declaration in
> the class, instead of the order they appear in the constructor
> initializer. This would introduce interdependencies. Therefore, it
> is safer to avoid such interdependence by assigning values to these
> members inside the constructor body rather than initializing them in
> the intializer. Could someone explain to me why this is the case?
> Moreover, what kind of error could possibly happen due to the
> "interdependency"?


Here is a contrived example, but it demonstrates the point:


#include <iostream>

struct Foo {
const int c;
int i;

Foo(int x) : c(x), i(2 * c) { }
};


struct Bar {
int i;
const int c;

Bar(int x) : c(x), i(2 * c) { }
};


int main()
{
using std::cout;

Foo f(3);
cout << f.c << ", " << f.i << '\n';

Bar b(3);
cout << b.c << ", " << b.i << '\n';
}


Output:
3, 6
3, 8529120


In Foo, first the const int c is initialized with the value of 3, then
the int i is initialized with the value of (2*3).

In Bar, since i was declared before c, then i's initialization occurs
first. At this point the value of c is garbage (and thus reading it is
really undefined behavior), so i is initialized with 2*garbage before c
is initialized.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
Jess
Guest
Posts: n/a
 
      04-28-2007
Many thanks for your explanations!

Jess

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help on constructor/constructor initialization list with inheritanceusing templates balaji C++ 3 08-10-2011 12:06 PM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
constructor and initializer Vincent RICHOMME C++ 1 01-14-2006 01:30 PM
composition/aggregation: would like to use constructor body rather than initializer list Chris K C++ 1 04-17-2004 08:38 PM
initialization in initializer list using copy constuctor?!? Alexander Stippler C++ 3 04-09-2004 01:53 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57