【问题标题】: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】:

    基类和派生类都有一个隐式的默认构造函数(以及复制和移动),不需要手动实现。

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

    所以,你的选择是:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-12
      • 2017-03-17
      • 2011-07-28
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多