3

Since C++2003 we have value-initialisation as well as default-initialisation. Meaning that:

struct Foo {
    int i;
    std :: string s;
};

Foo f1;          // f1.s is default-constructed, f1.i is uninitialised
Foo f2 = Foo (); // f1.s is default-constructed, f1.i is zero

Right?

Now suppose I have this class

class Bar : public Foo {
    int n;
    Foo f [SIZE];
public:
    Bar ();
};

When I write the constructor for Bar, I may want to default- or value-initialise either the parent class or the f[] member. I think the choice for initialising the parent is simply:

Bar :: Bar () : Foo (), n (-1) {} // Parent is value-initialised (Foo::i is zero)
Bar :: Bar () : n (-1)         {} // Parent is default-initialised (Foo::i is undefined)

But what about the f[] member?

  • How do I default-initialise all members?
  • How do I value-initialise all members?
  • If I use C++11 initializer lists, what happens if the initializer list has a different size than SIZE?
spraff
  • 32,570
  • 22
  • 121
  • 229
  • 3
    Please avoid spaces around `::`. – Antonio Pérez Feb 07 '12 at 08:56
  • 1
    Why? I like it, it's easier to read. – spraff Feb 07 '12 at 08:59
  • @spraff And yet you use PascalCaseWhereWordsRunTogether? – Pubby Feb 07 '12 at 09:05
  • 1
    For types, yes, for variables, no, and I don't give them LongNamesWhichSufferReadibilityProblems. But let's *not* have a style war in the comments. – spraff Feb 07 '12 at 09:11
  • In the first example _i_ will remain uninitialized in both default initialization and from-copy initialization, the difference is that in from-copy initialization _i_ will be initialized with garbage from the temporary Foo's member _i_. The from-copy initialization the way you use it is generally slower as it may result in temporary object creation (most compilers won't create extra copy though). – bobah Feb 07 '12 at 09:46

1 Answers1

1

Actually, according to standard value-initialization seems to be the process of calling whatever form of user-defined default constructor there or to zero-initialize objects which don't have a default constructor (see 8.5 [decl.init] paragraph 7:

To value-initialize an object of type T means:

— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.

— if T is an array type, then each element is value-initialized; — otherwise, the object is zero-initialized.

In this sense you can value initialize your array member since C++1998 using f() in the member initializer list. If you want to use specific values, you need to use C++2011 with an initializer list e.g. f({ 1, 2, 3 }). If there are fewer arguments than there are elements, the remaining elements are value initialized. Actually, the are initialized from an empty initializer list (8.5.1 [dcl.init.aggr] paragraph 7):

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list.

... and this initialization from an empty initializer list means according to 8.5.4 [dcl.init.list] paragraph 3, bullet 7:

  • Otherwise, if the initializer list has no elements, the object is value-initialized.
Community
  • 1
  • 1
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380