Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+;中是否存在未初始化的对象+;?_C++_Initialization - Fatal编程技术网

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。答案是否定的:

并不是所有的对象都有一个构造函数,例如 int >代码>。C++在某些情况下有这样一个有趣的概念:“缺省初始化不意味着初始化”,例如自动存储<代码> int n;代码>。所以它被初始化,但它没有初始化。你可以在<代码>类< /代码>内放置<代码> int >代码,除非初始化它,否则它将保持未初始化。IMO更容易将所有对象类型视为具有cor。只是对一些人来说,这些任务不是行动。因此,标准中的措辞有点混乱。当你写
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
不再初始化。