Item 13 in Meyer's Effective C++

D

Don Kim

In Meyer's EC++, Item 13, he offers this code snippet:

template<class T>
class Array {
public:
Array(int lowBound, int highBound);
....
private:
vector<T> data;

unsigned int size;
int lBound, hBound;
};

template<class T>
Array<T>::Array(int lowBound, int highBound)
: size(highBound - lowBound + 1), lBound(lowBound), hBound(highBound),
data(size) {}

He states that "class members are initialized in the order of their
declaration in the class; the order in which they are listed in a member
initialization list makes not a whit of difference". So in the "Array
template, data will always be initialized first, followed by size, lBound,
and hBound. Always".

I pretty much get what he is saying, but not clear as to why. Could anyone
elaborate or clarify? Thanks.

I'm trying to get my level of C++ knowledge to the next level, so I'm
reading both Stroupstrup's TCL and Meyer's EC++, which makes it very hard,
but rewarding.

-Don
 
V

Victor Bazarov

Don said:
In Meyer's EC++, Item 13, he offers this code snippet:

template<class T>
class Array {
public:
Array(int lowBound, int highBound);
...
private:
vector<T> data;

unsigned int size;
int lBound, hBound;
};

template<class T>
Array<T>::Array(int lowBound, int highBound)
: size(highBound - lowBound + 1), lBound(lowBound), hBound(highBound),
data(size) {}

He states that "class members are initialized in the order of their
declaration in the class; the order in which they are listed in a member
initialization list makes not a whit of difference". So in the "Array
template, data will always be initialized first, followed by size, lBound,
and hBound. Always".

I pretty much get what he is saying, but not clear as to why. Could anyone
elaborate or clarify? Thanks.

The answer to "why" is "because it is mandated so in the language
Standard". If you feel the need to ask the next [often seen as logical]
"why" -- "why is it so in the Standard", then you should ask in
comp.std.c++, since that's the place where they discuss the rationales
behind some decisions that affected (or about to affect) the Standard.
I'm trying to get my level of C++ knowledge to the next level, so I'm
reading both Stroupstrup's TCL and Meyer's EC++, which makes it very hard,
but rewarding.

You're on the right track.

Victor
 
A

Alf P. Steinbach

* "Don Kim said:
He states that "class members are initialized in the order of their
declaration in the class; the order in which they are listed in a member
initialization list makes not a whit of difference".

I pretty much get what he is saying, but not clear as to why. Could anyone
elaborate or clarify? Thanks.

C++ defines the initialization order as the order of declaration.

One possible reason for that is that destructors should be called in
the opposite order of constructors. And if you could influence the
initialization order in an initializer list then this order would have
to be remembered at run-time, for each and every object. Which would
introduce some overhead for each and every object.
 
H

Howard

Don Kim said:
In Meyer's EC++, Item 13, he offers this code snippet:

template<class T>
class Array {
public:
Array(int lowBound, int highBound);
...
private:
vector<T> data;

unsigned int size;
int lBound, hBound;
};

template<class T>
Array<T>::Array(int lowBound, int highBound)
: size(highBound - lowBound + 1), lBound(lowBound), hBound(highBound),
data(size) {}

He states that "class members are initialized in the order of their
declaration in the class; the order in which they are listed in a member
initialization list makes not a whit of difference". So in the "Array
template, data will always be initialized first, followed by size, lBound,
and hBound. Always".

Hmm... Looks like he's got an error there then, since size is not
initialized yet when data gets initialized. I would think that he'd have to
put size first in the class declarations to fix this (or else use the same
calculation as the initializer for data as he did for size). As it is, this
would generate undefined behavior, wouldn't it?

-Howard
 
P

Paul

Incidentally, be aware that this definitely does not hold in VC++6 (we
proved that the hard way! Out of order initializers don't appear to be used
at all). Don't assume how your compiler works until you've tested it, or
better yet, just initialize in the right order.
 
A

Andrey Tarasevich

Paul said:
Incidentally, be aware that this definitely does not hold in VC++6 (we
proved that the hard way! Out of order initializers don't appear to be used
at all). Don't assume how your compiler works until you've tested it, or
better yet, just initialize in the right order.
...

Can you produce a code snippet that demonstrates this behavior in VC++6?
 
P

Prateek R Karandikar

I pretty much get what he is saying, but not clear as to why. Could anyone
elaborate or clarify? Thanks.

Destruction should occur in the reverse order of construction. The
order of declarartion of members is fixed. However, there can be
several overloaded constructors, and the order in which members/bases
are listed for construction might be different in different
constructors. If that order was followed, the compiler wouldn't know
in what order to destroy members.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
F

Fraser Ross

Out of ordering initialising should not be done by any compiler. The
language rules say initialising starts from the topmost data member and
works downwards. You must take care with data member ordering - the
initialiser list ordering is unimportant but its sensible to make the
ordering the same as the data ordering.

Fraser.

"Paul"
 
G

Gregg

In Meyer's EC++, Item 13, he offers this code snippet:
[...]

He states that "class members are initialized in the order of their
declaration in the class; the order in which they are listed in a
member initialization list makes not a whit of difference". So in the
"Array template, data will always be initialized first, followed by
size, lBound, and hBound. Always".

I pretty much get what he is saying, but not clear as to why. Could
anyone elaborate or clarify? Thanks.

Note that a data member might not even appear in a constructor
initializer list, if it has a default constructor. The constructor
initializer list should be thought of as associating constructor
parameters with constructors for when they are invoked, not as
invocations of constructors.

In other words, base class constructor invoked first, followed by member
constructors in declaration order. If a member constructor appears in the
initializer list, use the parameters found there.

Gregg
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top