需要对C ++ 11标准中的8.5.p7进行一些澄清

时间:2013-07-18 20:37:48

标签: c++ c++11 initialization

C ++ 11标准的第8.5p7段规定:

  

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

     
      
  • 如果T是具有用户提供的构造函数的(可能是cv限定的)类类型(第9节)   (12.1),然后调用T的默认构造函数(和   如果T没有可访问的默认值,则初始化是错误的   构造函数);

  •   
  • 如果T是(可能是cv限定的)非联合类类型   没有用户提供的构造函数,那么对象就是   零初始化,如果T是隐式声明的默认构造函数   是非平凡的,那个构造函数被调用。

  •   
  • 如果T是数组类型,   然后每个元素都是值初始化的;

  •   
  • 否则,对象是   初始化为零。

  •   

我在理解上面粗体字符时遇到问题。额外调用T的隐式默认构造函数如何改变零初始化,这种情况刚刚发生?

3 个答案:

答案 0 :(得分:16)

这是一个具体的例子:

class A {
    int a;
public:
    A() : a(1) {}
};

class B {
    int b;
    A c;
};

B属于此类别 - 它是一个非联合类类型,没有用户提供的构造函数。因此,如果B是值初始化的,它将首先进行零初始化(因此bc.a都将设置为0),然后将调用默认构造函数(这将调用A的构造函数并将c.a设置为1)。

根据as-if规则,优化程序可以将这些组合成一个步骤(将b设置为0,将c.a设置为1),因为没有人可以查看零初始化和默认构造函数之间的对象。

答案 1 :(得分:5)

T可能没有自己的显式默认构造函数,但它可能来自U,它可以和/或具有类型V的成员。

答案 2 :(得分:4)

struct S {
    int a, b;
    S() : b(10) {}
};

struct T {
  S s;
};

int main() {
    S s{};
    T t{};
}

t已初始化值,T没有用户提供的构造函数。但是T隐式声明的默认构造函数并不简单。

s也是初始值,但S有一个用户提供的构造函数。

s.a将具有不确定的价值。但由于在默认构造函数调用之前的零初始化,t.s.a为零。 s.bt.s.b都设置为值10。