List of initializers for objects with a standard constructor

Is there any use to placing a class member variable in the initializer list, which does not have to be in the initializer list? Example:

class Foo { public: Foo() {} }; class Bar { public: Bar() : _foo() {} private: Foo _foo; }; 

In this case, does the compiler do something special?

+6
source share
4 answers

The initializer list is the preferred way to initialize elements into the constructor. This is the only possible way to initialize the link of members and permanent members.

Also, by using the list of initializers, you reduce the chance of accidentally using a variable before it is initialized. This is part of a broader philosophy of never defining a variable without initializing it.

+7
source

In this case, it does not matter.

But it can be useful to do.
If you have a large number of participants, then the presence of some, but not all members in the list can cause some confusion. It also strengthens the order of initialization at your disposal (the order is determined by the order of declaration in the class, but it can be useful to visualize this order in larger classes, where not all member variables are declared next to each other).

Note. If you put them in the wrong order in the list of internalizers, this is usually a warning for most compilers (unless you compile with warnings like errors (which you should)).

The real danger is with classes that have POD members and a constructor created by the compiler.

 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. } 
+9
source

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

The difference between Bar() : _foo() { } and the lack of an explicit default constructor Bar (or saying Bar() = default ) is that your version does not have a trivial default constructor. Thus, the values โ€‹โ€‹of std::is_trivially_constructible<Bar>::value will be different from if you leave the construct and shy, anyway, although the behavior is otherwise the same.

+6
source

No, in this case nothing else is done. I see no use for this.

+1
source

All Articles