Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializer list for objects with default constructor

Is there any benefit to putting a class member variable in an initializer list that doesn't need to be in an initializer list? Example:

class Foo
{
public:
  Foo() {}
};

class Bar
{
public:
  Bar() : _foo() {}

private:
  Foo _foo;
};

Does the compiler do anything special, in this case?

like image 362
MarkP Avatar asked Nov 05 '12 18:11

MarkP


4 Answers

In this case it makes no difference.

But it can be useful to do so.
If you have a large number of members then having some but not all members in the list can cause some confusion. Also it reinforces in your mind the order of initialization (the order is defined by the order of declaration in the class, but it can be useful to visualize this order in larger classes where not all the member variables are declared beside each other).

Note: If you put them in the wrong order in the internalizer list this is usually just a warning on most compilers (unless you compile with warnings as errors (which you should)).

The real danger is with classes that have a POD members and compiler generated constructor.

class NewFoo
{
      int x;
      int y;
};
// Version 1:
class Bar1
{
     NewFoo  f;
};
// Version 2:
class Bar2
{
     NewFoo  f;
     public:
         Bar2()  // f not in list.
         {}
};
// Version 3:
class Bar3
{
     NewFoo  f;
     public:
         Bar3()
            : f()
         {}
};

int main()
{
     Bar1     b1a;           // x and y not  initialized.
     Bar1     b1b = Bar1();  // x and y zero initialized.
     Bar2     b2a;           // x and y not  initialized.
     Bar2     b2b = Bar2();  // x and y not  initialized.
     Bar3     b3a;           // x and y zero initialized.
     Bar3     b3b = Bar3();  // x and y zero initialized.
}
like image 111
Martin York Avatar answered Sep 23 '22 23:09

Martin York


An initializer list is the preferred way to initialize the members in a constructor. It is the only possible way to initialize reference members and constant members.

Also by using an initializer list, you reduce the chances of accidentally using the variable before it has been initialized. It's part of the larger philosophy of never defining a variable without initializing it.

like image 38
Syntactic Fructose Avatar answered Sep 22 '22 23:09

Syntactic Fructose


Members that are not mentioned in the initializer list of the constructor which is being used are default-initialized. For Foo this means that the default constructor will be called.

The difference between Bar() : _foo() { } and not giving Bar an explicit default constructor at all (or saying Bar() = default is that your version doesn't have a trivial default constructor. Thus the values of std::is_trivially_constructible<Bar>::value will differ from if you left the construc­tor out altogether, though the behaviour is otherwise the same.

like image 21
Kerrek SB Avatar answered Sep 24 '22 23:09

Kerrek SB


No, nothing different is done in this case. I don't see any benefit to doing this.

like image 28
bames53 Avatar answered Sep 24 '22 23:09

bames53