简体   繁体   中英

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?

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.

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