C++ C+;中是否存在未初始化的对象+;?
如果所有对象都至少有一个构造函数,无论是编译器定义的默认构造函数还是用户定义的构造函数,那么对象如何可以不初始化。该标准没有讨论对象的存在,但是,有一个对象生存期的概念C++ C+;中是否存在未初始化的对象+;?,c++,initialization,C++,Initialization,如果所有对象都至少有一个构造函数,无论是编译器定义的默认构造函数还是用户定义的构造函数,那么对象如何可以不初始化。该标准没有讨论对象的存在,但是,有一个对象生存期的概念 void foo() { int i; // i's lifetime begins after this line, but i is uninitialized // ... } 具体而言,从† 类型为T的对象的生存期始于: 获得类型T的正确对齐和尺寸的存储,以及 如果对象具有非真空初始化,则其初始化
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
具体而言,从†
类型为T
的对象的生存期始于:
- 获得类型
的正确对齐和尺寸的存储,以及T
- 如果对象具有非真空初始化,则其初始化已完成
int
s),它们的生命周期在获得存储后就开始了,即使它们没有被初始化
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
†添加链接是为了便于阅读,它们不会出现在标准中可以声明未执行初始化的对象。这些对象确实存在,它们有一个不确定的值,并且使用该值是未定义的行为(对于chars,此规则有一个例外) 默认情况下,可以创建这样的对象。 这是在C++标准中声明的,(11.6个初始化器)[DLC.init ]: 默认初始化T类型的对象意味着: (7.1)-如果T是一种(可能是cv合格的)类别类型(第12条),则考虑施工人员。适用的 枚举构造函数(16.3.1.3),通过重载选择初始值设定项()的最佳构造函数 决议(16.3)。调用这样选择的构造函数(参数列表为空),以初始化 反对 (7.2)-如果T是数组类型,则每个元素默认初始化
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
(7.3)-否则,不执行初始化。
然而,静态对象总是零初始化的。因此,任何具有动态或自动存储持续时间的内置项都可能不会初始化,即使它是子对象
int i; //zero-initialized
struct A{
int i;
};
struct B
{
B(){};
B(int i)
:i{i}{}
int i;
int j;
};
A a; //a.i is zero-initialized
int main()
{
int j; //not initialized
int k{}; //zero-initialized
A b; //b.i not initialized
int* p = new int; //*p not initialized
A* q = new A; //q->i not initialized
B ab; //ab.i and ab.j not initialized
B ab2{1}; //ab.j not initialized
int xx[10]; //xx's element not initialized.
int l = i; //OK l==0;
int m = j; //undefined behavior (because j is not initialized)
int n = b.i; //undefined behavior
int o = *p; //undefined behavior
int w = q->i; //undefined behavior
int ex = x[0] //undefined behavior
}
对于成员初始化[class.base.init]可能有帮助:
在非委托构造函数中,如果给定的潜在构造的子对象未由mem指定-
初始值设定项id(包括没有mem初始值设定项列表的情况,因为构造函数没有
(初始化器),然后
-如果实体是具有默认成员初始值设定项(12.2)的非静态数据成员,并且
(9.1.1)-构造函数的类是一个联合体(12.3),未指定该联合体的其他变体成员
通过mem初始值设定项id或
(9.1.2)-构造函数的类不是联合体,如果实体是匿名联合体的成员,则
该联盟的其他成员由mem初始值设定项id指定,
根据11.6中规定的默认成员初始值设定项初始化实体
(9.2)-否则,如果实体是匿名联盟或变体成员(12.3.1),则不允许初始化
表演
(9.3)-否则,实体默认初始化(11.6)
普通匿名联合的成员也可能无法初始化
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
还有人可能会问,对象的生命周期是否可以在不进行任何初始化的情况下开始,例如通过使用reinterpret_cast。答案是否定的:并不是所有的对象都有一个构造函数,例如
inti代码>,i
默认初始化。但是int
的默认初始化定义为“不执行初始化”。通俗地说,我们称之为not initialized.int i是默认初始化的,据我所知,int的默认c'tor并不初始化它(或者i被初始化为不确定值)。如果没有默认的c'tor,它将被称为未初始化(毫无疑问),但是如果存在默认的c'tor,那么它可以以任何方式初始化对象,即使它选择取消初始化对象也可能被视为某种形式的初始化,那么为什么它应该被视为未初始化//我只是一个初学者,如果我错了,我会纠正我anywhere@rimiro“未初始化”指的是对象的状态,而不是构造函数是否已运行。因此,如果默认的c'tor不执行任何操作,则对象保持未初始化状态,其值不确定代码>未初始化,但int x[10]代码>零是否已初始化?这似乎不对,你是否还遗漏了另一个条款?如果我的记忆没有对我撒谎,这些都记录在斯特劳斯特鲁普的书中!我支持您的情况。@markransem数组没有什么特别之处,不执行初始化。您可以在这里查看程序集:对不起,我没有意识到7.2是一个递归定义。要么是这样,要么是我严重误读了。什么,没有新的位置<代码>::新建((void*)&a)a代码>和a.i
不再初始化。