C++中是否存在未初始化的对象?

rim*_*ire 15 c++ initialization

如果所有对象至少有一个构造函数,则由编译器或用户定义的默认c'tor定义,那么对象如何未初始化.

Oli*_*liv 14

可以声明执行初始化的对象.这些对象确实存在,它们具有不确定的值,并且使用此值是未定义的行为(此规则对于字符有例外).

可以通过默认初始化来创建此类对象.这在c ++标准(第11.6节初始化程序)[dlc.init]中说明:

缺省初始化类型的对象T表示:

(7.1) - 如果T是(可能是cv限定的)类类型(第12条),则考虑构造函数.枚举适用的构造函数(16.3.1.3),通过重载解析(16.3)选择初始化函数()的最佳构造函数.使用空参数列表调用如此选择的构造函数来初始化对象.

(7.2) - 如果T是数组类型,则每个元素都是默认初始化的.

(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
   }
Run Code Online (Sandbox Code Playgroud)

对于成员初始化[class.base.init]可能会有所帮助:

在非委托构造函数中,如果给定的可能构造的子对象不是由mem-initializer-id指定的(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer),那么 - 如果entity是一个非静态数据成员,具有默认成员初始值设定项(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) - 否则,实体默认初始化(11.6)

一个简单的匿名联盟的成员也可能没有被初始化.


也可以通过使用reinterpret_cast来询问是否可以在没有任何初始化的情况下开始对象生命周期.答案是否定的:reinterpret_cast创建一个简单的默认构造对象


Pas*_* By 2

该标准没有谈论对象的存在,但是有一个对象生命周期的概念。

\n

具体来说,来自[basic.life] \xe2\x80\xa0

\n
\n

类型对象的生命周期T从以下时间开始:

\n
    \n
  • T获得具有正确对齐方式和类型大小的存储,并且

    \n
  • \n
  • 如果对象具有非空初始化,则其初始化已完成

    \n
  • \n
\n
\n

非空初始化定义为

\n
\n

如果一个对象属于类或聚合类型,并且该对象或其子对象之一是由除普通默认构造函数之外的构造函数初始化的,则称该对象具有非空初始化。

\n
\n

我们可以得出结论,对于具有空初始化的对象(例如ints),它们的生命周期在获取存储空间后立即开始,即使它们未初始化。

\n
void foo()\n{\n    int i;  // i\'s lifetime begins after this line, but i is uninitialized\n    // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\xa0 添加链接是为了方便阅读,它们不会出现在标准中

\n