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?
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.
}
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.
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 constructor out altogether, though the behaviour is otherwise the same.
No, nothing different is done in this case. I don't see any benefit to doing this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With