添加成员变量的子类的构造

Rid*_*ick 5 c++ inheritance constructor

在我的程序中,我有一个抽象类,几个类继承自该抽象类。每个子类都会引入一个成员变量来存储数据。我注意到,当尝试初始化子类时,无论是使用聚合初始化还是初始值设定项列表,都会出现错误,如下所示。

struct FooBase {};
struct Foo : FooBase { int value; };

int main()
{
    Foo f = {8}; // "initializer for aggregate with no elements requires explicit braces"
    Foo f{8};    // same error as above
}
Run Code Online (Sandbox Code Playgroud)

我认为这是因为 Foo 继承了 FooBase 的构造函数,但我对此行为有几个问题。

  • 既然类型是在编译时指定的,为什么 的聚合构造函数不Foo优先?
  • 有没有办法强制默认构造函数的优先级,以便可以进行上述初始化?
  • (更广泛一点)一般来说,类的(标准和聚合)构造函数如何传递给它们的子类?

据我了解,选项将是在初始化后设置数据(或创建 setter 方法)或显式定义Foo. 然而,特别是在最后一个问题的背景下,移动和复制构造函数会发生什么?(是否有良好的实践来确保类在继承下表现良好?)

r3m*_*n0x 5

在您的示例中,您需要提供额外的空大括号来初始化基类:

Foo f = {{}, 8};
Foo f{{}, 8};
Run Code Online (Sandbox Code Playgroud)

但一般来说,并不是每个类都可以聚合初始化。如果该类具有以下内容,则该类被视为聚合(请参阅源代码):

  • 没有私有或受保护的非静态数据成员
  • 没有用户提供的、继承的或显式的构造函数(允许显式默认或删除的构造函数)
  • 没有虚拟、私有或受保护的基类
  • 没有虚拟成员函数

此外,不存在“聚合构造函数”这样的东西,并且默认构造函数与聚合初始化没有任何关系。

基类的构造函数不会被继承,除非您经常using Base::Base这样做。复制和移动构造函数也不被继承。它们由编译器为每个类自动生成,除非显式定义或隐式删除它们。

  • @Riddick,它被称为[列表初始化](https://en.cppreference.com/w/cpp/language/list_initialization),它按一定顺序考虑类的构造函数,实际上**与初始化列表不同** 。初始化列表通常指“std::initializer_list”,它可用于模拟类似数组的类的聚合初始化(例如“std::vector”)。 (2认同)