避免使用虚方法构造空基 class 的构造函数

Avoid constructor with empty base class with virtual method

我有一个带有虚函数的空基 class。有什么方法可以避免手动实现 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);
}

Is there any way I can avoid manually implementing the constructors of Derived in order to be able to initialize it?

没有。拥有基础 class 和虚函数会导致 Derived 不是聚合。

如果你删除 virtual 函数,你就有了聚合,你可以

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

但这不是你问题的重点,所以这不是解决问题的方法。

基础 class 和派生 class 都有一个隐式默认构造函数(以及复制和移动),无需手动实现它们。

class 都不是聚合,因此如果不实现接受兼容参数列表的自定义构造函数,就无法使用列表初始化来初始化它们。这就是您的示例程序不起作用的原因。如果不删除虚拟成员函数,class 都不能成为聚合。

那么,您的选择是:

  • 不要使用列表初始化,除非参数为空列表,这是一种特殊情况,它执行调用默认构造函数的值初始化
  • 或者为要传递的参数列表提供自定义构造函数
  • 或者去掉虚成员函数,让classes变成聚合体,然后可以直接用列表初始化
  • 来初始化它们的成员