在不同的派生类中继承具有不同参数的纯虚方法

时间:2018-12-13 00:58:21

标签: c++ inheritance design-patterns

我已经在基类中声明了一个纯虚方法,但是我想使不同派生类中的参数集不同。

我当前的代码是基类中的重载函数,如下所示:

class Base {
protected:
    virtual void function(arg_set_first) = 0;
    virtual void function(arg_set_second) = 0;
}

class Derived_First: public Base {
private:
    void function(arg_set_first);
    void function(arg_set_second) { } // do nothing
}

class Derived_Second: public Base {
private:
    void function(arg_set_first) { } // do nothing
    void function(arg_set_second);
}

它可以工作,但是我认为这很丑陋,因为每个派生类中都有多余的实现。我要删除它们。

如何在基类中将纯虚函数更改为具有可变的参数集,该参数集将在实施时指定?有办法吗?

1 个答案:

答案 0 :(得分:0)

严格来说,您无法在C ++中做到这一点-方法的参数列表(以及这些参数的类型)被视为方法的 type-signature 的一部分,因此如果子类的虚拟方法共享相同的名称和确切的参数,则它们只能重写/实现父类的虚拟方法。

也就是说,您可以通过使用数据结构而不是直接传递参数来伪造它。例如:

class Base {
protected:
    virtual void function(const std::map<std::string, std::variant> & args) = 0;
}

有了上述内容,您就有了一种方法,该方法可以采用一组键值对形式的任何命名参数。然后,由子类(及其调用者)决定要使用的参数名称和参数值。这种方法的缺点是效率低下且难以使用(调用方每次要调用该方法时都必须创建并填充std::map,并且该方法必须检查{{1 }}并找出如何处理它们);但是,如果灵活性是您的首要考虑因素,而性能却不是(例如,因为该方法不会经常被调用),则此方法可以很好地工作。

另一种方法是使用多重继承,并为这两种方法分别指定单独的接口,并且(为方便起见)还为要实现这两种方法的子类提供接口类:

std:map

由于任何特定的调用代码都知道它将要调用哪个class BaseFirst { protected: virtual void function(arg_set_first) = 0; } class BaseSecond { protected: virtual void function(arg_set_second) = 0; } class BaseBoth : public BaseFirst, public BaseSecond { }; class Derived_First: public BaseFirst { private: virtual void function(arg_set_first) {...} }; class Derived_Second: public BaseSecond { private: virtual void function(arg_set_second) {...} }; class Derived_Both: public BaseBoth { private: virtual void function(arg_set_first) {...} virtual void function(arg_set_second) {...} }; 方法(而不会),因此可以在其API中简单地指定适当的指针/引用类型(例如{ {1}},functionBaseFirst *)来反映其要求,编译器将为您保证只有实际满足这些要求的对象才能传递给它。