默认构造函数是否初始化内置types?
默认构造函数(由编译器创build)是否初始化内置types?
隐式定义(由编译器)类的默认构造函数不会初始化内置types的成员。
但是,您必须记住,在某些情况下,类的实例的初始化可以通过其他方式执行。 不是默认的构造函数,也不是构造函数。
例如,对于C
类, C()
总是调用默认的构造函数,这是一个普遍的错误信念。 但实际上,语法C()
执行所谓的类实例的值初始化 。 它只会调用默认的构造函数,如果它是用户声明的 。 (这是C ++ 03。在C ++ 98中 – 只有当类是非POD时)。 如果类没有用户声明的构造函数,那么C()
将不会调用编译器提供的默认构造函数,而是执行一种特殊types的初始化,根本不涉及C
的构造函数。 相反,它会直接重新初始化每个class级的成员。 对于内置types,它会导致零初始化。
例如,如果你的类没有用户声明的构造函数
class C { int x; };
那么编译器会隐式提供一个。 编译器提供的构造函数什么也不做,这意味着它不会初始化C::x
C c; // Compiler-provided default constructor is used // Here `cx` contains garbage
不过,下面的初始化将会初始化x
因为它们使用了explicit ()
初始化器
C c = C(); // Does not use default constructor for `C()` part // Uses value-initialization feature instead assert(cx == 0); C *pc = new C(); // Does not use default constructor for `C()` part // Uses value-initialization feature instead assert(pc->x == 0);
()
初始化器的行为在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(cx == 0); C d{}; // C++11 style aggregate initialization. assert(dx == 0);
为了所有的实际目的 – 没有。
但是对于技术上符合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
但是,在现实世界中,这不是很好的支持,所以不要使用它。
标准的相关部分是8.5.5和8.5.7节
我不太确定你的意思,但是:
struct A { int x; }; int a; // a is initialized to 0 A b; // bx is initialized to 0 int main() { int c; // c is not initialized int d = int(); // d is initialized to 0 A e; // ex is not initialized A f = A(); // fx is initialized to 0 }
在每种情况下,我说“未初始化” – 你可能会发现你的编译器给它一个一致的值,但标准不需要它。
许多手势都被抛出,包括我在内,关于内置types“实际上”是如何具有默认的构造函数的。 实际上,默认的初始化和值初始化是标准中定义的术语,我个人必须每次查询。 只有在标准中定义的类才具有隐式的默认构造函数。
按照标准,它不会除非你在初始化列表中明确初始化
正如前面的发言者所说 – 不,他们没有初始化。
这实际上是一个真正奇怪的错误的来源,因为现代操作系统倾向于用新零填充新分配的内存区域。 如果你期望的话,这可能是第一次。 但是,随着应用程序继续运行, delete
和new
对象,您迟早会遇到期望为零,但早期对象的剩余边距不为零的情况。
那么,为什么这样呢,并不是所有new
分配的数据? 是的,但并不总是从操作系统。 操作系统倾向于使用更大的内存块(例如,每次4MB),所以所有这些小的一字三字节分配和解除分配都是在uyrspace中处理的,因此不会被清零。
PS。 我写了“倾向于”,即你第一次不能依靠成功…
从技术上讲,它会初始化它们 – 通过使用它们的默认构造函数,它偶然不会为它们分配内存。
如果你想知道的是他们是否被设置为像int
那样健全的东西,那么答案是“否”。
默认构造函数分配内存并调用任何父项的无参数构造函数。