是否有必要在构造函数初始化列表中调用默认构造函数?
Is it ever necessary to invoke default ctor in constructor initialization list?
例如,如果我有以下内容:
class Foo; // has default ctor
class Bar {
public:
Bar(Foo* f);
}
class MyClass {
public:
MyClass();
private:
Foo foo_;
Bar bar_;
}
MyClass::MyClass() : foo_(), bar_(&foo) {}
这或多或少地在没有警告的情况下进行编译,请参见https://godbolt.org/g/yx464A[稍作修改,使 Foo 充实]。
它也可以在初始化列表中没有 foo_() 的情况下正常编译。但是有没有需要调用默认构造函数的情况?
嗯,foo_
将被默认初始化:
[C++11: 12.6.2/8]:
In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then
- if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
- otherwise, if the entity is a variant member (9.5), no initialization is performed;
- otherwise, the entity is default-initialized (8.5).
这是否是您想要的取决于您。对于 POD,默认初始化(不会对 POD 成员做任何事情)可能还不够。对于具有要初始化的非 POD 成员的实际默认构造函数的 class,初始化将按照您的预期进行级联。
例如,如果我有以下内容:
class Foo; // has default ctor
class Bar {
public:
Bar(Foo* f);
}
class MyClass {
public:
MyClass();
private:
Foo foo_;
Bar bar_;
}
MyClass::MyClass() : foo_(), bar_(&foo) {}
这或多或少地在没有警告的情况下进行编译,请参见https://godbolt.org/g/yx464A[稍作修改,使 Foo 充实]。
它也可以在初始化列表中没有 foo_() 的情况下正常编译。但是有没有需要调用默认构造函数的情况?
嗯,foo_
将被默认初始化:
[C++11: 12.6.2/8]:
In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then
- if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
- otherwise, if the entity is a variant member (9.5), no initialization is performed;
- otherwise, the entity is default-initialized (8.5).
这是否是您想要的取决于您。对于 POD,默认初始化(不会对 POD 成员做任何事情)可能还不够。对于具有要初始化的非 POD 成员的实际默认构造函数的 class,初始化将按照您的预期进行级联。