【问题标题】:Value initialization for classes with exclusively inherited constructors具有独占继承构造函数的类的值初始化
【发布时间】:2013-12-13 20:16:30
【问题描述】:

根据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;
}

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

【问题讨论】:

    标签: c++ c++11 value-initialization


    【解决方案1】:

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

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

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


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

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

    D2B2 的候选继承构造函数集是
    B2(const B2&amp;)
    B2(B2&amp;&amp;)
    B2(int = 13, int = 42)
    B2(int = 13)
    B2()

    D2 中存在的构造函数集是
    D2(),隐式声明的默认构造函数,不继承
    D2(const D2&amp;),隐式声明的复制构造函数,不继承
    D2(D2&amp;&amp;),隐式声明的移动构造函数,不继承
    D2(int, int),隐式声明的继承构造函数
    D2(int),隐式声明的继承构造函数

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

    A()
    A(int)
    A(const& A)
    A(A&&)
    

    B 中的构造函数是

    B() implicitly declared, not inherited
    B(int) implicitly declared, inherited
    B(const& B) implicitly declared, not inherited
    B(B&&) implicitly declared, not inherited
    

    【讨论】:

    • 我认为将最后一段移到答案的开头会更清楚。
    猜你喜欢
    • 2018-01-30
    • 2014-04-02
    • 1970-01-01
    • 2014-10-23
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多