12

C++11 标准的第 8.5p7 段指出:

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

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

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

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

  • 否则,对象被零初始化。

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

4

3 回答 3

16

这是一个具体的例子:

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

class B {
    int b;
    A c;
};

B属于这一类——它是一个非联合类类型,没有用户提供的构造函数。所以如果 aB是值初始化的,它首先会被初始化为零(所以两者都bc.a被设置为 0),然后会调用默认的构造函数(它将调用A的构造函数并设置c.a为 1)。

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

于 2013-07-18T20:54:21.167 回答
5

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

于 2013-07-18T20:43:21.153 回答
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有一个用户提供的构造函数。

s.a会有一个不确定的值。但t.s.a由于调用默认构造函数之前的零初始化,所以为零。两者s.bt.s.b都设置为值 10。

于 2013-07-18T20:58:17.517 回答