[英]C++ Class Inheritance separate methods in derived class
我得到了MachineLearning
, MachineLearningSVM
和MachineLearningAdaboost
三个类。
MachineLearning
是基类, MachineLearningSVM
和MachineLearningAdaboost
从中派生的。
class MachineLearning; //Base class
class MachineLearningSVM : public MachineLearning;
class MachineLearningAdaboost : public MachineLearning;
class `MachineLearning` {
public:
virtual void Train();
}
class MachineLearningSVM : public MachineLearning {
public:
void Train(std::vector<Feature> features);
}
class MachineLearningAdaboost : public MachineLearning {
public:
void Train(std::vector<Feature> features, std::vector<Label> labels);
}
我的问题是,我想告诉所有派生类它们应该保留一个函数Train(),但是每个派生类在其方法定义中应该能够具有不同的参数。 如上所述,Adaboost需要(示例性地)需要其他标签来进行培训。
考虑以下:
int main(){
MachineLearning* ml;
switch(type){
case SVM:
ml = new MachineLearningSVM();
break;
case Adaboost:
ml = new MachineLearningAdaboost();
break;
}
ml->Train(std::vector<Feature>);
}
C ++在编译时不知道要调用哪个Train函数,因为不清楚它是SVM还是Adaboost类型。
我如何实现这种情况? 我想避免使用模板。
您从根本上误解了多态和继承的概念。 派生类必须与基类具有is-a关系: MachineLearningSVM
是 MachineLearning
,尤其是基类中声明的virtual
函数(但在派生类中定义或重写)可以从指向基类的指针进行调用。
在您的示例中,这没有任何意义:
MachineLearning*ptr = get_machine_learning(); // can be either derived class
ptr->Train(); // we don't know which derived class so what do you
// want to pass as arguments???
您可以定义一个更灵活的接口,但是您仍然遇到相同的问题(例外情况显而易见):
struct MachineLearning
{
void Train(std::vector<Feature> const&features)
{
if(need_labels()) throw std::runtime_error("need labels to train");
train(features);
}
void Train(std::vector<Feature> const&features,
std::vector<Label> const&labels)
{
if(!need_labels()) std::cerr<<"WARNING: ignoring labels for training\n";
train(features,labels);
}
virtual~MachineLearning() {}
protected:
virtual void train(std::vector<Feature> const&) = 0;
virtual void train(std::vector<Feature> const&,
std::vector<Label> const&) = 0;
virtual bool need_labels() const = 0;
};
struct MachineLearningSVM : MachineLearning
{
protected:
bool need_labels() const { return false; }
void train(std::vector<Feature> const&features) override;
void train(std::vector<Feature> const&features,
std::vector<Label> const&) override
{ train(features); }
};
struct MachineLearningAdaboost : public MachineLearning
{
protected:
bool need_labels() const { return true; }
void train(std::vector<Feature> const&) override
{ throw std::runtime_error("need labels for training"); }
void train(std::vector<Feature> const&features,
std::vector<Label> const&labels) override;
};
这些错误和警告是不良代码设计的标志...
这里的麻烦在于,在C ++函数签名中使用其名称创建参数,并将参数的类型传递给它。 基类不包含签名功能
void Train(std::vector<Feature> features);
因此您的编译器开始大喊大叫。 您可以从技术上仅通过声明虚拟功能来修复代码,但这实际上不起作用,因为您的设计中存在问题,如previos响应中所述。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.