C++类继承在派生类中分离方法
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 trainingn";
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);
因此编译器开始大喊大叫。从技术上讲,你可以通过声明虚拟函数来修复你的代码,但它不会真正起作用,因为你的设计中存在问题,正如前面的响应中提到的那样。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 将非类库分离为标头和实现的方法
- 使用 CLion 在不同文件中分离 Boost 测试套件的正确方法
- 在GTKMM中,在分离的线程中发生失效后,on_draw方法将停止调用
- 有没有一种方法可以在C++11中取消/分离未来
- C++类继承在派生类中分离方法
- 什么是c++中分离头/源的模板专门化的健壮方法?
- c++ 11线程是否提供了一种在主线程退出后分离线程继续的方法?
- 我们是否可以在不同的类中分离主序列化方法,以便使用c++的boost库使其更容易和不那么复杂?