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

时间:2018-06-27 18:25:55

标签: 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
}

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

  • 由于类型是在编译时指定的,为什么Foo的聚合构造函数没有优先级?
  • 有没有一种方法可以强制使用默认构造函数的优先级,以便可以进行上述初始化?
  • (更广泛的说法),通常,(标准和聚合)类的构造函数如何传递给子对象?

据我了解,这些选项将是在初始化(或使用setter方法)后设置数据,或显式定义Foo的构造函数。但是,特别是在最后一个问题的上下文中,移动和复制构造函数会发生什么? (是否存在确保类在继承下表现良好的良好实践?)

2 个答案:

答案 0 :(得分:3)

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

Foo f = {{}, 8};
Foo f{{}, 8};

虽然通常来说,并不是每个类都可以被聚合初始化。如果具有该类,则认为该类是集合(请参见source

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

此外,没有“聚合构造函数”之类的东西,默认构造函数与聚合初始化没有任何关系。

基类的构造函数不会被继承,除非您使用using Base::Base进行继承。复制和移动构造函数也未继承。除非明确定义或隐式删除它们,否则编译器会为每个类自动生成它们。

答案 1 :(得分:2)

默认构造函数是不带参数且value initializes类的所有成员的构造函数;使用int并使用其初始化value的构造函数必须是用户定义的构造函数。

构造函数不会传递给其子级。如果在using FooBase::FooBase的定义中添加using declaration Foo,则FooBase的所有构造函数都将在Foo中变为可见(尽管在此示例中,此设置无效) FooBase仅包含默认提供的构造函数。