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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2417065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:25:33  来源:igfitidea点击:

Does the default constructor initialize built-in types?

c++constructorinitializationdefault-constructorbuilt-in-types

提问by Siggi

Does the default constructor (created by the compiler) initialize built-in-types?

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

回答by AnT

Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.

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

However, you have to keep in mind that in some cases the initialization of a instance of the class can be performed by other means. Not by default constructor, nor by constructor at all.

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

For example, there's a widespread incorrect belief that for class Cthe syntax C()always invokes default constructor. In reality though, the syntax C()performs so called value-initializationof the class instance. It will only invoke the default constructor if it is user-declared. (That's in C++03. In C++98 - only if the class is non-POD). If the class has no user-declared constructor, then the C()will not call the compiler-provided default constructor, but rather will perform a special kind of initialization that does not involve the constructor of Cat all. Instead, it will directly value-initialize every member of the class. For built-in types it results in zero-initialization.

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

For example, if your class has no user-declared constructor

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

class C { 
public:
  int x;
};

then the compiler will implicitly provide one. The compiler-provided constructor will do nothing, meaning that it will not initialize C::x

那么编译器将隐式提供一个。编译器提供的构造函数什么都不做,意味着它不会初始化C::x

C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage

Nevertheless, the following initializations willzero-initialize xbecause they use the explicit ()initializer

尽管如此,以下初始化零初始化,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);

The behavior of ()initializer is different in some respects between C++98 and C++03, but not in this case. For the above class Cit will be the same: ()initializer performs zero initialization of C::x.

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

Another example of initialization that is performed without involving constructor is, of course, aggregate initialization

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

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);

回答by Steve Jessop

I'm not quite certain what you mean, but:

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

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
}

In each case where I say "not initialized" - you might find that your compiler gives it a consistent value, but the standard doesn't require it.

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

A lot of hand-waving gets thrown around, including by me, about how built-in types "in effect" have a default constructor. Actually default initialization and value initialization are defined terms in the standard, which personally I have to look up every time. Only classes are defined in the standard to have an implicit default constructor.

关于内置类型“有效”如何具有默认构造函数的问题,包括我在内的很多人都在挥手致意。其实默认初始化和值初始化是标准中定义的术语,我个人每次都必须查找。只有类在标准中定义为具有隐式默认构造函数。

回答by JoeG

For all practical purposes - no.

出于所有实际目的 - 不。



However for implementations that are technically compliant with the C++ standard, the answer is that it depends whether the object is POD or not and on how you initialize it. According to the C++ standard:

然而,对于技术上符合 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

However, in the real world, this isn't well supported so don't use it.

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



The relevant parts of the standard are section 8.5.5 and 8.5.7

标准的相关部分为8.5.5和8.5.7

回答by mukeshkumar

As per the standard, it doesn't unless you explicitly initialize in initializer list

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

回答by e8johan

As previous speakers have stated - no, they are not initialized.

正如之前的发言者所说 - 不,他们没有被初始化。

This is actually a source for really strange errors as modern OSs tend to fill newly allocated memory regions with zeroes. If you expect that, it might work the first time. However, as your application keeps running, delete-ing and new-ing objects, you will sooner or later end up in a situation where you expect zeroes but a non-zero leftover from an earlier object sits.

这实际上是一个非常奇怪的错误来源,因为现代操作系统倾向于用零填充新分配的内存区域。如果您期望这样,它可能会在第一次起作用。但是,随着您的应用程序不断运行delete-ing 和new-ing 对象,您迟早会遇到一种情况,即您期望为零,但来自早期对象的非零剩余物位于。

So, why is this then, isn't all new-ed data newly allocated? Yes, but not always from the OS. The OS tends to work with larger chunks of memory (e.g. 4MB at a time) so all the tiny one-word-here-three-bytes-there-allocations and deallocations are handled in uyserspace, and thus not zeroed out.

那么,为什么这是new新分配的所有-ed 数据?是的,但并不总是来自操作系统。操作系统倾向于使用更大的内存块(例如一次 4MB),因此所有微小的一个字-这里-三个-字节-那里-分配和释放都在用户空间中处理,因此不会被清零。

PS. I wrote "tend to", i.e. you can't even rely on success the first time...

附注。我写了“倾向于”,即你甚至不能依靠第一次成功......

回答by Peter Alexander

Technically it does initialize them -- by using their default constructor, which incidentally does nothing but allocate the memory for them.

从技术上讲,它确实初始化了它们——通过使用它们的默认构造函数,顺便说一下,它只为它们分配内存。

If what you wanted to know is whether or not they are set to something sane like 0 for ints, then the answer is "no".

如果您想知道它们是否为ints设置为 0 之类的正常值,那么答案是否定的。

回答by JUST MY correct OPINION

No. The default constructor allocates memory and calls the no-argument constructor of any parents.

否。默认构造函数分配内存并调用任何父级的无参数构造函数。