内置类型的成员是否默认初始化?

ste*_*wer 4 c++ constructor primitive-types

我最近遇到了我的一个类的问题,因为我没有在构造函数初始化列表中设置指向NULL的指针,所以当我运行程序时它包含垃圾.

然而,虽然我知道在堆栈上声明但未初始化的内置类型的实例将包含随机值,但我很确定我会读到某处,因为未在构造函数初始化列表中明确放置的类成员将具有其默认值对于内置类型调用的构造函数,这也会发生,在大多数平台上插入像伪构造函数一样的代码,将它们设置为零我还认为我在某些情况下在某些情况下读到了"在C++中思考"构造对象的内存将被清零,但在两种情况下我似乎都是错误的.

请有人确认一下,
a)内置类型成员的初始化与是否定义了用户定义的构造函数有关,
b)是否需要初始化内置类型的成员手动,和
c)是否有任何情况下,在调用构造函数之前,对象的存储被清零?

此外,在研究这个问题时,我已经看到使用了"默认初始化"和"零初始化"这两个术语 - 说:

T a;
Run Code Online (Sandbox Code Playgroud)

T a();
Run Code Online (Sandbox Code Playgroud)

?我认为第一种形式只是用来防止歧义,当第二种形式可以被编译器作为函数声明.

非常感谢您的宝贵时间,

stellarpower

Bri*_*ian 12

首先让我们来看一些例子和正确的术语.

T a1;            // default initialization
T a2{};          // value initialization
T();             // also value initialization
new T;           // default initialization
new T();         // value initialization
new T{};         // also value initialization
class C1 {
    C1() {}
    T x;
};               // no initializer for C1::x; default-initialized
class C2 {
    T x;
};               // implicit default constructor default-initializes C2::x
class C3 {
    C3() : x() {}
    T x;
};               // C3::x will be value-initialized.
class C4 {
    C4() : x{} {}
    T x;
};               // C4::x will also be value-initialized.
// DANGER
T a();           // declares a function; not value initialization (quirk of C++)
Run Code Online (Sandbox Code Playgroud)

通常,规则是当没有初始化器时,它是默认初始化,并且当初始化器是()或时{},它是值初始化.请注意,静态和线程局部有一个例外,我将在后面讨论.

对于整数或浮点类型,值初始化将其设置为0.对于指针类型,值初始化将其设置为null.默认初始化对标量类型没有任何作用.因此,如果标量类型的对象仅接收默认初始化,则它具有不确定的值.

a)内置类型成员的初始化与定义或不定义用户定义的构造函数有关,

类的默认构造函数default-initializes成员.如果没有为其明确提供mem-initializer,则也会对成员进行默认初始化.实施例C1C2说明这一点.但是,请注意,当类类型进行了值初始化,并且类的默认构造函数被隐式定义或显式默认时,类的成员将被清零.这种清零仅在这种情况下发生,并且对于用户提供的默认构造函数不会发生.因此,从这个意义上说,你的问题的答案是肯定的.

C1 y1;   // y1 is default-initialized; y1.x is indeterminate
C1 y2{}; // y2 is value-initialized;   y2.x is indeterminate
C2 y3;   // y3 is default-initialized; y3.x is indeterminate
C2 y4{}; // y4 is value-initialized;   y4.x is set to 0
C3 y5;   // y5 is default-initialized; y5.x is set to 0
C3 y6{}; // y6 is value-initialized;   y6.x is set to 0
Run Code Online (Sandbox Code Playgroud)

b)内置类型的成员是否总是需要手动初始化,以及c)是否存在在调用构造函数之前对象的存储被清零的任何情况?

我假设你的意思是"具有内置类型的类成员".我在上面介绍了一个案例,其中它们被自动初始化为0:其中类对象是值初始化的,其构造函数不是用户提供的(或删除的).另一种情况是类对象具有静态或线程本地存储持续时间.在这种情况下,成员也会在一开始就归零,因此他们没有机会以不确定的价值结束.