【问题标题】:Avoid constructor with empty base class with virtual method避免使用带有虚方法的空基类的构造函数
【发布时间】:2019-09-04 10:46:50
【问题描述】:
我有一个带有虚函数的空基类。有什么方法可以避免手动实现 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);
}
【问题讨论】:
标签:
c++
inheritance
constructor
initialization
c++17
【解决方案1】:
有什么方法可以避免手动实现 Derived 的构造函数以便能够对其进行初始化?
没有。拥有基类和虚函数会导致 Derived 不是聚合。
如果您删除 virtual 函数,则您有聚合并且可以
return Derived{{}, 5}.f(3);
// ^^ explicitly initialize base class
但由于这不是你的问题的重点,所以这不是解决方案。
【解决方案2】:
基类和派生类都有一个隐式的默认构造函数(以及复制和移动),不需要手动实现。
这两个类都不是聚合,因此如果不实现接受兼容参数列表的自定义构造函数,就无法使用列表初始化对其进行初始化。这就是您的示例程序不起作用的原因。如果不删除虚成员函数,这两个类都不能成为聚合。
所以,你的选择是:
- 不要使用列表初始化,除非有一个空的参数列表,这是一种执行值初始化并调用默认构造函数的特殊情况
- 或为要传递的参数列表提供自定义构造函数
- 或删除虚成员函数,使类成为聚合,然后可以直接使用列表初始化对其成员进行初始化