Stack object creation in C++ - Alternative syntax [duplicate]
Possible Duplicate:
What do the following phrases mean in C++: zero-, default- and value-initialization?
I am confused about an issue in C++.
When creating an object on the stack using the default constructor, I thought either one of the following two syntax notations would give the same result:
class MyClass { public: int i; }
int main()
{
MyClass a = MyClass();
MyClass b;
}
However, the first syntax initializes the field to zero, whereas the second one leaves the field uninitialized. So my questions ar开发者_开发技巧e:
- Why is this so? I thought fields in C++ were not supposed to be automatically initialized.
- Is there any other differences between the two syntaxes?
- Do these syntax variations have separate names to distinguish them from each other?
I’m currently using Microsoft Visual C++ 2010 Express. Thanks!
In the first, you copy-initialize a
from a value-initialized instance of MyClass
. From the C++03 standard, §8.5/7:
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
And from §8.5/5:
To value-initialize an object of type
T
means:
- if
T
is a class type with a user-declared constructor, then the default constructor forT
is called (and the initialization is ill-formed ifT
has no accessible default constructor);- if
T
is a non-union class type without a user-declared constructor, then every non-static data member and base-class component ofT
is value-initialized;- if
T
is an array type, then each element is value-initialized;- otherwise, the object is zero-initialized
To zero-initialize an object of type
T
means:
- if
T
is a scalar type, the object is set to the value of0
(zero) converted toT
;- if
T
is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;- if
T
is a union type, the object’s first named data member) is zero-initialized;- if
T
is an array type, each element is zero-initialized;- if
T
is a reference type, no initialization is performed.
In the second, you declare b
in a manner that would cause it to be default-initialized if MyClass
were not a POD type -- §8.5/5:
To default-initialize an object of type T means:
- if
T
is a non-POD class type, the default constructor forT
is called (and the initialization is ill-formed ifT
has no accessible default constructor);- if
T
is an array type, each element is default-initialized;- otherwise, the object is zero-initialized.
However, because MyClass
is a POD type, b
is uninitialized -- §8.5/9:
If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a non-static object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any of its subobjects are of const-qualified type, the program is ill-formed.
Basically, this is a (relatively) simple WTF in the language, where primitive types will not be initialized by default. The first syntax explicitly initializes them- the second doesn't. User-defined types will always be initialized, so it's only meaningful if you don't initialize it in the constructor, and it will be an error if you don't call the init functions of UDTs that need them.
UDTs that do not do anything insane should not require the first syntax and it's normal to use the second.
精彩评论