我已经在基类中声明了一个纯虚方法,但是我想使不同派生类中的参数集不同。
我当前的代码是基类中的重载函数,如下所示:
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);
}
它可以工作,但是我认为这很丑陋,因为每个派生类中都有多余的实现。我要删除它们。
如何在基类中将纯虚函数更改为具有可变的参数集,该参数集将在实施时指定?有办法吗?
答案 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}},function
或BaseFirst *
)来反映其要求,编译器将为您保证只有实际满足这些要求的对象才能传递给它。