On May 2, 2:08 am, Jess <w...@hotmail.comwrote:
I tried several books to find out the details of object
initialization. Unfortunately, I'm still confused by two specific
concepts, namely default-initialization and value-initialization.
Don't feel bad. The definitions for these two have changes
several times. The simplest solution for the everyday use is to
consider them synonyms, and not worry about the subtle
differences. If you design your classes correctly, they
shouldn't really be relevant anyway.
I think default-init calls default constructor for class
objects and sets garbage values to PODs.
No. At least, not as it is defined in the standard.
Value-init also calls default
constructor for class objects and sets 0s to POD types. This is what
I've learned from the books (especially Accelerated C++).
I think that Andy wrote the book before the term
value-initialization was added to the standard; he probably was
defining some terms of his own, just to try to avoid confusion.
Roughly speaking:
-- If an object has a user defined constructor---any user
defined constructor, it is impossible to create an instance
of the object without calling a constructor. Period.
Whether the object is a sub-object, or stands alone. You
don't have to worry about different types of initialization
in this case, since they're all the same.
-- For everything but POD types, you should ensure that the
object has a constructor which initializes everything. Once
you have to provide a constructor, there's no point in doing
a half way job. So again, you don't have to worry about the
different types of initialization.
-- For PODs, there are three cases:
. objects with static lifetime, and objects initialized by
an empty (), are zero initialized,
. objects with a explicit initializer are always
completely initialized---fields with missing initializer
values will be zero initialized, and
. everything else is uninitialized, random garbage.
The different types of initialization only become relevant when
you have constructors which only do a half-way job.
However, I don't think my understanding about these concepts
is adequate and I'm not sure under what situations each of
these two init methods is used. Therefore, I'm posting my
questions below along with what I understand about these two
init methods. I'd appreciate it if someone could answer my
questions and point out my mistakes. Thanks.
1. Default initialization is used when we create an object using the
form "T t", where T can be a POD type or class type.
No. According to the standard (ISO 14882:1998), default
initialization is used in this case if the object is of non-POD
class type, otherwise, no initialization is done.
If this happens, the following occurs:
a. if T is POD, then "t" is garbage value
b. if T is class, then it's default constructor is invoked. If
there's no default contructor, the compiler will synthesize one.
(i). If there's a default constructor, then all T's POD member data is
initialized according to the constructor initializer list; any POD
member not mentioned in the initializer list gets default-init, with
garbage value. If T has a class-typed member (say of type A), then
A's default constructor is called and if A has no default constructor,
then the synthesized constructor will be called. FInally, the
constructor's body is entered.
(ii). If there is no default constructor, then the synthesized
constructor will be called. All POD member gets garbage data and
class members have their default constructor (or synthesized default
constructors) invoked.
That's corresponds pretty well to the effect. With one
exception: if there is any user defined constructor, the
compiler will not synthesize a default constructor. If there is
one or more user defined constructors, but no user defined
default constructor, you cannot create an instance of the class
without specifying some arguments for initialization.
Is this what happens to default-init?
It's what happens "by default", when initializing an object with
no explicit initialization list, provided the object doesn't
have static storage duration.
Moreover, to init POD member in
the constructor initializer, I can do things like "x(10)" and also
"x()" where "x" is an int, is this right? If "x()" is used, then "x"
gets value-init to 0?
Roughly speaking, X() initializes the object with the value it
would have as an object with static storage duration; i.e. as if
it were zero initialized, and then any non-trivial constructor
were called on it.
2. Value-initialization happens if a constructor is explicitly invoked
like "T t(arg)", its copy constructor is invoked. For a class type
object:
Not in the standard. That's explicit initialization. It can
only be used for a class type, and overload resolution is used
on the argument list to decide which constructor to call.
a. if it's created by invoking a constructor like "T t(arg)", then all
its POD member gets initialized according to the constructor
initializer; any POD member not mentioned gets value-init to 0.
No. If the object has static storage duration, it will be
initially zero initialized, and then the constructor will be
called, otherwise, the constructor will be called directly.
If the object doesn't have class type, then this is the
equivalent of:
T t = arg ;
But
what happens to those class-typed members? Are their default
constructors (or synthesized one) called? I think after all these are
done, the constructor's body is entered.
All constructors systematically call the constructors of all
sub-objects, if those sub-objects have a non-trivial
constructor.
b. if the T object is created through copy constructor, then the
values of the existing objects are copied into the new object.
However, what if we have an example like "B b = B()"? what's the value
of the tmp object created by "B()"? Is it the result of default-init
or value-init?
Yes:-). According to ISO 14882::1998, it is default-init;
according to the latest draft, it is value-init, but if you are
writing reasonable code, it doesn't matter.
3. To value-init a POD object, I think the only way is to do something
like:
int n = int();
is this right?
value-initialization and default-initialization are the same
thing for POD objects.
4. The book Accelerated C++ also says that if an object is used to
init a container element, either as a side effect of adding new
element to a "map", or as the elements of a container defined to have
a given size, then the members will be value-initialized. I checked
it through an example,
struct A{
int x;
};
int main(){
A a[10];
Attention: this is NOT a container, at least not in the sense
Accelerated C++ means in tha above statement.
return 0;
};
Then I found out each element in a has it's "x" value as 0.
Or something else. The initial value is not specified, and any
attempt to read it is undefined behavior, so you could end up
with everything 0. You could also end up with values that cause
a core dump when read, if such exist on the machine in question.
I think
this is what the author of the book meant. Then I tried another
example:
int main(){
int b[10];
return 0;
}
You're reading Accelerated C++, right? Doesn't that book
normally use std::vector<intfor arrays?
This time, each element in b has garbage value. Isn't each member of
b supposed to be value-init to 0?
There's no difference in your two examples. In both cases, the
objects are simply not initialized.
--
James Kanze (GABI Software) email:ja*********@gmail.com
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