默认构造函数是否初始化内置类型?

167 c++ constructor initialization default-constructor built-in-types

默认构造函数(由编译器创建)是否初始化内置类型?

AnT*_*AnT 164

隐式定义(由编译器)类的默认构造函数不初始化内置类型的成员.

但是,您必须记住,在某些情况下,可以通过其他方式执行类实例的初始化.不是默认构造函数,也不是构造函数.

例如,有一种普遍的错误信念,即对于类C,语法C()总是调用默认构造函数.但实际上,语法C()执行所谓 的类实例的值初始化.如果是用户声明的,它只会调用默认构造函数.(那是在C++ 03中.在C++ 98中 - 只有当类是非POD时).如果类没有用户声明的构造函数,那么C()它将不会调用编译器提供的默认构造函数,而是执行一种特殊的初始化,它根本不涉及构造函数C.相反,它将直接初始化类的每个成员.对于内置类型,它会导致零初始化.

例如,如果您的类没有用户声明的构造函数

class C { 
  int x;
};
Run Code Online (Sandbox Code Playgroud)

然后编译器将隐式提供一个.编译器提供的构造函数将不执行任何操作,这意味着它不会初始化C::x

C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage
Run Code Online (Sandbox Code Playgroud)

然而,以下初始化零初始化,x因为它们使用显式()初始化器

C c = C(); // Does not use default constructor for `C()` part
           // Uses value-initialization feature instead
assert(c.x == 0);

C *pc = new C(); // Does not use default constructor for `C()` part
                 // Uses value-initialization feature instead
assert(pc->x == 0);
Run Code Online (Sandbox Code Playgroud)

()初始化程序的行为在C++ 98和C++ 03之间在某些方面是不同的,但在这种情况下不是这样.对于上面的类C,它将是相同的:()初始化器执行零初始化C::x.

在不涉及构造函数的情况下执行的初始化的另一个示例当然是聚合初始化

C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);

C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);
Run Code Online (Sandbox Code Playgroud)

  • 在C++ 11中:`C c {}`用`0`初始化`x`? (19认同)
  • 如果你做`C()= default;`,这是如何工作的?这仍然会对`new C();以及`new C的默认初始化'执行值初始化;`? (13认同)
  • 注意!根据http://stackoverflow.com/a/3931589/18775,Visual Studio C++编译器中存在一个错误,C c = C(); 可能并不总是有效. (4认同)
  • @MarkIngram有点晚了但是是的:如果你使用`C()= default;`,你将得到`new C();'的值初始化以及`new C;`的默认初始化.请参阅:http://stackoverflow.com/a/42049188/746890 (3认同)
  • 这个答案很好,但是只讨论`C`是POD的情况。如果此答案可以提及当情况不平凡或非标准布局时情况如何变化,那就太好了。 (2认同)

Joe*_*oeG 19

出于所有实际目的 - 没有.


但是,对于技术上符合C++标准的实现,答案是它取决于对象是否是POD以及如何初始化它.根据C++标准:

MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized
Run Code Online (Sandbox Code Playgroud)

但是,在现实世界中,这并没有得到很好的支持,所以不要使用它.


标准的相关部分是第8.5.5和8.5.7节


Ste*_*sop 18

我不太确定你的意思,但是:

struct A { int x; };

int a; // a is initialized to 0
A b;   // b.x is initialized to 0

int main() {
    int c;         // c is not initialized
    int d = int(); // d is initialized to 0

    A e;           // e.x is not initialized
    A f = A();     // f.x is initialized to 0
}
Run Code Online (Sandbox Code Playgroud)

在我说"未初始化"的每种情况下 - 您可能会发现编译器为其提供了一致的值,但标准并不要求它.

包括我在内的很多挥手问题都是关于内置类型"有效"的默认构造函数.实际上,默认初始化和值初始化是标准中定义的术语,我个人每次都必须查找.只有标准中定义的类才具有隐式默认构造函数.


muk*_*mar 3

根据标准,除非您在初始值设定项列表中显式初始化,否则不会

  • 好吧,你不能在编译器创建的默认构造函数中指定任何内容 (3认同)
  • @Gorpik - 要点...但是当我说显式初始化时,我的意思是必须显式提供默认构造函数 (2认同)