C++ 默认构造函数是否初始化内置类型?
默认构造函数(由编译器创建)是否初始化内置类型?根据标准,除非您在初始值设定项列表中显式初始化,否则它不会初始化。默认构造函数分配内存并调用任何父级的无参数构造函数。从技术上讲,它会初始化它们——使用它们的默认构造函数,顺便说一句,它只为它们分配内存C++ 默认构造函数是否初始化内置类型?,c++,constructor,initialization,default-constructor,built-in-types,C++,Constructor,Initialization,Default Constructor,Built In Types,默认构造函数(由编译器创建)是否初始化内置类型?根据标准,除非您在初始值设定项列表中显式初始化,否则它不会初始化。默认构造函数分配内存并调用任何父级的无参数构造函数。从技术上讲,它会初始化它们——使用它们的默认构造函数,顺便说一句,它只为它们分配内存 如果您想知道它们是否被设置为正常值,如ints的0,那么答案是“否”。如前面的发言者所述-否,它们没有初始化 这实际上是一个非常奇怪的错误源,因为现代操作系统倾向于用零填充新分配的内存区域。如果你预料到这一点,它可能会在第一时间起作用。但是,随着应
如果您想知道它们是否被设置为正常值,如
int
s的0,那么答案是“否”。如前面的发言者所述-否,它们没有初始化
这实际上是一个非常奇怪的错误源,因为现代操作系统倾向于用零填充新分配的内存区域。如果你预料到这一点,它可能会在第一时间起作用。但是,随着应用程序继续运行,delete
-ing和new
-ing对象,您迟早会遇到这样一种情况,即您期望为零,但早期对象的非零剩余物仍然存在
那么,为什么不是所有的新的-ed数据都是新分配的呢?是的,但并不总是来自操作系统。操作系统倾向于使用更大的内存块(例如,每次4MB),因此所有的小一个字(此处为三个字节)分配和释放都在uyservice中处理,因此不会归零
注:我写了“倾向于”,也就是说,你甚至不能第一次就依赖于成功…所有的实际目的-不
<>但是,对于技术上符合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; // 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
}
在我说“未初始化”的每一种情况下,您可能会发现编译器给了它一个一致的值,但标准并不要求它
包括我在内的很多人都在讨论内置类型“实际上”是如何拥有默认构造函数的。实际上,默认初始化和值初始化是标准中定义的术语,我个人每次都要查找这些术语。标准中仅定义类具有隐式默认构造函数。隐式定义(由编译器)类的默认构造函数不会初始化内置类型的成员
但是,您必须记住,在某些情况下,类实例的初始化可以通过其他方式执行。不是默认构造函数,也不是完全由构造函数
例如,人们普遍错误地认为,对于类C
,语法C()
总是调用默认构造函数。但实际上,语法C()
执行类实例的所谓值初始化。如果默认构造函数是用户声明的,它将只调用默认构造函数。(这在C++03中,在C++98中-仅当类为非POD时)。如果类没有用户声明的构造函数,那么C()
将不会调用编译器提供的默认构造函数,而是执行一种特殊的初始化,它根本不涉及C
的构造函数。相反,它将直接初始化类的每个成员。对于内置类型,它会导致零初始化
例如,如果您的类没有用户声明的构造函数
class C {
public:
int x;
};
然后编译器将隐式地提供一个。编译器提供的构造函数不会执行任何操作,这意味着它不会初始化C::x
C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage
但是,以下初始化将零初始化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);
在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);
那么,您不能在由compiler@Gorpik--注意……但我说的是显式初始化,我的意思是必须显式提供默认值constructor@hype:我知道,但OP指定他说的是计算机创建的默认构造函数,不是你自己提供的。还有任何非POD成员的无参数构造函数。构造函数是否分配内存,或者编译器是否为实例“分配”内存,然后调用构造函数?这个答案是非常错误的。。。1/构造函数不分配任何内存,而是对其进行初始化。2/问题是关于内置的,这个答案是关于父类的。。。为什么这个错误的离题答案得到了8票?分配内存?这是从哪里来的?我觉得有趣的是,这有9个上升票和5个下降票,而排名靠前的答案有5个上升票和0个下降票。全局值呢,它们不是总是零初始化的吗?除了第一个,没有调用默认构造函数。事实上,它们的默认构造函数也做同样的事情(它们不初始化任何东西)——毕竟它们都是同一个类。在第四种情况下,编译器只使用值初始化POD,而不调用默认构造函数。@FredOverflow,所有命名空间作用域和本地或类静态对象都是零初始化的,与它们的类型无关(它们可能是最复杂的类,但仍然是零初始化的)。“不会初始化内置成员”这是什么意思?注意!VisualStudioC++编译器中的bug和C C= C.();在C++11中:将C{}
用0
初始化x
?Ho