C ++:由隐式构造函数初始化int变量

时间:2013-07-17 02:30:14

标签: c++ constructor int

我正在学习C ++,我对int变量的初始化感到有些困惑。

此代码(包括评论)是Nawaz在本主题中的答案的复制/粘贴Why does C++ require a user-provided default constructor to default-construct a const object?

struct POD
{
  int i;
};

POD p1; //uninitialized - but don't worry we can assign some value later on!
p1.i = 10; //assign some value later on!

POD p2 = POD(); //initialized

对于p2,我知道发生了以下情况:

  • 调用默认构造函数POD()以创建临时POD对象。构造函数不是用户定义的,因此它是隐式的。对于像int这样的内置类型,隐式默认构造函数不执行任何操作(不进行初始化)。因此 i 包含一些随机的东西。
  • 使用临时POD对象(其 i 仍未初始化)调用复制构造函数来创建p2。因此,不应该初始化p2的i成员。

然而,评论说p2已初始化! 欢迎任何解释。感谢。

2 个答案:

答案 0 :(得分:7)

  

对于像int这样的内置类型,隐式默认构造函数什么都不做(没有初始化)。

这是事实,但也不是。默认初始化会导致单元化对象,而值初始化则不会。

为什么这些案件有所不同?

1。 C ++ 11,8.5 / 11

  

如果为对象指定了 no initializer ,则默认初始化该对象;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定值

如果您使用int i;,则会产生未初始化的整数!

2。 C ++ 11,8.5 / 10

  

一个对象,其初始化程序是一组空的括号,即(),应该是值初始化

如果您使用int i = int();,则您的值已初始化i。现在,什么是价值初始化?

3。 C ++ 11,8.5 / 7

  

值初始化 T 类型的对象意味着

     
      
  • [...](T可能是类或数组类型的一些选项)
  •   
  • 否则,对象零初始化。
  •   

好了,现在我们知道int i = int();表示有i=0

由于您的结构是POD,因此初始化值意味着对其所有成员进行初始化。

您可以使用常规行为的快捷方式

int i1, i2 = int();
std::cout << i1 << std::endl;
std::cout << i2 << std::endl;

如果i1所在的内存不是零运气,那么输出可能会

somevalue
0

[正如@jogojapan正确提到的:首先从i1读取未定义,所以不要这样做。你很可能会观察我在这里所描述的内容,但由于标准没有强制编译器以这种方式表现i1可能为零,或以任何其他奇怪的方式制止预期结果。]

请注意以下事项:

  

注意:由于初始化程序的语法不允许使用(),

     
X a();
     

不是类X的值初始化对象的声明,而是函数的声明,不带参数并返回X.

强调标准报价是我的。

答案 1 :(得分:3)

如果类类型POD没有用户定义的构造函数(在您的示例中就是这种情况),则POD() 不会调用默认构造函数。而是在不使用任何构造函数的情况下创建对象。编译器执行临时对象的所谓值初始化。值初始化是一种自给自足的初始化方法,它不一定使用构造函数。相反,整个对象的值初始化递归地一个接一个地执行其所有子对象的值初始化。对于int类型的成员,值初始化意味着零初始化。

这就是POD().i保证为零的原因。任何构造者都没有放置零。通过值初始化将零放在那里。