具有独占继承的构造函数的类的值初始化

Tom*_*uwé 6 c++ value-initialization c++11

根据cppreference,没有任何用户提供的构造函数的非联合类类型在构造之前将被初始化为零:

如果T是没有任何用户提供的构造函数的非联合类类型,则该对象被零初始化,然后调用隐式声明的默认构造函数(除非它是微不足道的)

我不确定当使用c ++ 11继承的构造函数时会发生什么,因为引用显式地提到了隐式声明的默认构造函数.

给出以下示例:

#include <iostream>

struct A {
    int a;
    A() {}
    A(int i): a(i) {}
};

struct B: public A {
    using A::A;
};

int main() {
    B b { 5 };
    B* p = new (&b) B{ };
    std::cout << b.a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

什么是正确的输出,0或5?在value-initialization(B{ })之前,是否应该专门提供继承的构造函数的类类型进行零初始化?

Pra*_*ian 6

正确答案是0因为默认构造函数B是隐式声明的.

请注意,默认,复制和移动构造函数不会被继承; 引自§12.9/ 3 [class.inhctor]

对于除了没有参数的构造函数或具有单个参数的复制/移动构造函数之外的候选继承构造函数集中的每个非模板构造函数,构造函数隐式声明具有相同的构造函数特征,除非存在用户声明的构造函数完整类中的相同签名,其中出现using声明或构造函数将是该类的默认,复制或移动构造函数.


您的示例类似于N3797中列出的示例,§12.9/ 6(为简洁起见而编辑)

struct B2 {
  B2(int = 13, int = 42);
};

struct D2 : B2 {
  using B2::B2;
};
Run Code Online (Sandbox Code Playgroud)

D2for 的继承构造函数的候选集B2
- B2(const B2&)
- B2(B2&&)
- B2(int = 13, int = 42)
- B2(int = 13)
-B2()

构造函数的集合D2
- D2(),隐式声明的默认构造函数,不是继承的
- D2(const D2&),隐式声明的复制构造函数,不是继承的
- D2(D2&&),隐式声明的移动构造函数,不是继承的
- D2(int, int),隐式声明的继承构造函数
- D2(int),隐式声明的继承构造函数

在您的情况下,Bfor 的继承构造函数的候选集A

A()
A(int)
A(const& A)
A(A&&)
Run Code Online (Sandbox Code Playgroud)

存在的构造函数B

B() implicitly declared, not inherited
B(int) implicitly declared, inherited
B(const& B) implicitly declared, not inherited
B(B&&) implicitly declared, not inherited
Run Code Online (Sandbox Code Playgroud)