简体   繁体   中英

Default-initialized vs. Value-initialized

From this answer , In C++03, a POD type gets default initialized if () is omitted otherwise it is value-initialized.

// POD type
struct foo {
     int x;
};

// value-initialized
new foo();

But if a user-defined constructor is provided, is any of the objects below will be considered as default or value-initialized ?

// non-POD type
struct bar {
     bar(int x = 0):x(x) {}
     int x;
};

new bar();
new bar(42);

In C++03, a POD type gets default initialized if () is omitted otherwise it is value-initialized.

That is not exactly what happens. According to the C++03 spec, section 8.5/9, if no initializer is specified for a non-static POD-type object, then it and its sub-objects "have an indeterminate initial value". That is not the same thing as default-initialization. Default-initialization is the same thing as value-initialization for a POD-type, which would mean the object is zero-initialized (8.5/5), but that can only happen with the presence of an empty initializer (ie, empty-parenthesis per 8.5/7). Thus you can only default and/or value-initialize a POD-type with an empty initializer. Default initialization for a non-static POD-type does not happen when no initializer is specified.

In your second example, with the non-POD type that has the user-defined constructor, default-initialization would technically take place if you omitted the value-initializer (parenthesis) symbols. In other words:

bar* ptr_a = new bar; //default initialization
bar* ptr_b = new bar(); //value initialization

Keep in mind though that with both non-POD struct or class-types, if there is a user-defined constructor, default-initialization and value initialization, per 8.5/5, both call the user-defined constructor. So in the end, with the type bar as you've declared it, default and value initialization end up doing the same thing.

If your class has a user-defined default constructor, then both default and value initialization cause that constructor to be called. Whatever happens next is up to the constructor:

struct UDT
{
  int a;
  int b;
  Foo c;
  Foo d;
  UDT() : a(), c() {}
};

Both default and value initialization of an object of class UDT will cause UDT::a and UDT::c to be value-initialized (so a is zero) because the initializer list says so, while UDT::b and UDT::d are themselves default-initialized (so b is uninitialized, and for d apply the same logic recursively).

For details on initialization, see 8.5, and on initializer lists see 12.6.2 (esp. clause 8).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM