避免使用带有虚方法的空基类构造函数

时间:2019-09-04 10:46:50

标签: c++ inheritance constructor initialization c++17

我有一个带有虚函数的空基类。有什么方法可以避免手动实现Derived的构造函数以便对其进行初始化?

struct Base
{
    virtual int f(int) const = 0;
    virtual ~Base() = 0; 
};

Base::~Base() {}

struct Derived: public Base
{
    int v;

    int f(int) const override{ return v;};
};

int main() 
{
    return Derived{5}.f(3);
}

2 个答案:

答案 0 :(得分:5)

  

有什么办法可以避免手动实现Derived的构造函数以便对其进行初始化?

不。具有基类和虚函数会导致Derived不是聚合。

如果您删除了virtual函数,那么您就可以进行汇总了

return Derived{{}, 5}.f(3);
//             ^^ explicitly initialize base class

但这不是您要问的重点,所以这不是解决方案。

答案 1 :(得分:1)

基类和派生类都具有隐式的默认构造函数(以及复制和移动),因此无需手动实现它们。

这两个类都不是聚合,因此如果不实现一个接受兼容参数列表的自定义构造函数,则无法使用列表初始化对其进行初始化。这就是示例程序无法运行的原因。在不删除虚拟成员函数的情况下,任何一个类都不能成为集合。

因此,您的选择是:

  • 不使用列表初始化,除非使用空的参数列表,这是一种特殊情况,它执行值初始化,并调用默认构造函数
  • 或为您要传递的参数列表提供自定义构造函数
  • 或删除虚拟成员函数,使类成为聚合,然后可以使用列表初始化直接初始化其成员