繁体   English   中英

C ++类继承在派生类中的单独方法

[英]C++ Class Inheritance separate methods in derived class

我得到了MachineLearningMachineLearningSVMMachineLearningAdaboost三个类。

MachineLearning是基类, MachineLearningSVMMachineLearningAdaboost从中派生的。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM