C 中存在非初始化的对象
Do uninitialized objects exist in C++?
如果所有对象至少具有一个构造函数,则默认是由编译器或用户定义的默认c'tor。
可以声明对对象进行不执行初始化。这些对象确实存在,它们具有不确定的值,并且使用此值是未定义的行为(该规则对字符有例外)。
可以通过 default-intialization 创建此类对象。这在C 标准(§11.6初始化器)[dlc.init]中说明了:
to default-initialize 类型的对象表示:
(7.1) - 如果t是(可能是CV值的)类类型(第12条),则考虑构造函数。适用 列举构造函数(16.3.1.3),并且通过超载选择了 initializer ()的最佳构造函数 决议(16.3)。因此,选择的构造函数被称为空的参数列表,以初始化 对象。
(7.2) - 如果t是数组类型,则每个元素被默认为initialized。
(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]可能会有所帮助:
在非级别的构造函数中 initializer-id(包括没有mem-Initializer列表的情况,因为构造函数没有 ctor-Initializer),然后 - 如果该实体是具有默认成员初始化器(12.2)和
的非静态数据成员(9.1.1) - 构造师的班级是工会(12.3),该工会的其他变体成员没有指定 由mem-initializer-id或
(9.1.2) - 构造人的班级不是工会,如果实体是匿名联盟的成员,则没有 该工会的其他成员是由Mem-Initializer-ID指定的, 该实体是根据11.6中指定的默认成员初始化器初始化的。
(9.2) - 否则,如果实体是匿名联盟或变体成员(12.3.1),则没有初始化是 执行;
(9.3) - 否则,实体被默认为initialization(11.6)
微不足道的匿名联盟的成员也可能不会初始化。
还可以通过使用reinterpret_cast来询问对象寿命是否可以开始而无需任何初始化,以示出。答案是 no :reinterpret_cast创建一个琐碎的默认构造对象
标准不谈论对象的存在,但是,对象有一个 lifetimes 的概念。
具体来说,来自[basic.life] †
类型
T
对象的寿命开始:
获得了适当的对齐和大小
T
的存储,并且如果对象的初始化不变,则其初始化已完成
非胶合初始化定义为
如果对象是类型或聚合类型的对象,则具有非胶合初始化,并且它或其一个子对象之一是由构造函数初始化的。
我们可以得出结论,对于具有空置初始化的对象(例如int
s),他们的寿命在获取存储后立即开始,即使将它们保持不可原始化。
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
†链接添加以易于阅读,它们不会出现在标准
使用字节数组:
alignas(alignof(Mat4)) uint8_t result[sizeof(Mat4)];
// ..
node->updateMatrix( ..., /*result*/ reinterprect_cast<Mat4*>(&result[0]));
Mat4
的构造函数不会触发。
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 对象初始化中是否允许指向此成员的指针?
- 对象初始化后在C++中显示 char 数组时的异常行为
- 为什么两种不同的对象初始化方式给出不同的输出
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- afxmem.cpp中的对象初始化差异
- 删除通过取消引用新对象初始化的对象
- 如何使用sregex_token_iterator对象初始化向量
- 关于默认构造函数,对象初始化/使用C++ OOP
- C++ 基元类型初始化与对象初始化
- 哪个函数负责C++全局范围内的类对象初始化?
- C++中构造函数的对象初始化出现问题
- 如何修复模板 BST 类的对象初始化
- 无法在 QML/C++ 中使用绑定对象初始化 UI
- 为什么参数可以在对象初始化时通过赋值运算符传递给构造函数?
- 类对象初始化的二维向量
- GCC:当层次结构中存在虚拟继承时,C++11 内联对象初始化(使用 "this")不起作用
- 对象初始化
- 类对象初始化
- 使用从另一个类继承的类的对象初始化成员对象