我遇到了多态类和继承问题。
我有一个父类
CHARINDEX
我有两个孩子
calibration.h
class Calibration {
private:
public:
void init();
void calc():
void close();
void saveFile();
}
calibration.cpp
Calibration::Calibration(){}
void Calibration::saveFile(){
std::ofstream out;
out.open("cores.arff");
out << " " << std::endl;
out.close();
}
我如何更正来自automatic.cpp
Automatic::Automatic(){}
void Automatic::config(){
....
}
void Automatic::calibrate(){
....
}
void Calibrate::init(){
Automatic::config();
}
manual.h
#include "calibration.h"
class Manual : public Calibration {
public:
void calibrate();
}
manual.cpp
Manual::Manual(){}
void Manual::calibrate(){
....
}
void Calibrate::init(){
Manual::calibrate();
}
的来电Manual::calibrate
和Automatic::config
?
我试过了:
Calibrate::init()
但我得到的错误是:
错误:没有在“自动”类中声明的成员函数
答案 0 :(得分:2)
在面向对象编程中,这个问题最好用成员函数重载来解决。
制作Calibrate::init()
虚拟
virtual void init();
重载每个子类中的init方法,并在每个子类中调用子特定的方法。
class Manual : public Calibration {
public:
void init();
void calibrate();
}
Manual::init()
{
this->calibrate();
}
答案 1 :(得分:1)
最简单的路由是只有一个函数calibrate
是虚拟的,并被Calibration
的子类覆盖。
为此,我更喜欢并演示纯虚函数。如果子类没有实现纯虚拟calibration
,编译器将捕获错误。如果纯虚拟不是您的类层次结构的正确选择,请将子项的calibrate
方法定义为void calibrate() override;
,以便在calibrate
方法更改且不再匹配时捕获将来的错误。
有一个强有力的理由使calibrate
成为受保护的函数,以便不能直接调用它,强制Calibration
的用户使用init函数并确保设备完全初始化
为了保持以下代码清洁,我删除了未使用的函数。
#include <iostream>
class Calibration {
public:
virtual ~Calibration() {}; // must specify virtual destructor to ensure
// proper destruction of all classes involved
void init();
virtual void calibrate() = 0; // pure virtual function must be implemented
// by children or compile will fail
};
// two subclasses to demonstrate
class Automatic : public Calibration {
private:
void config(); // called through calibrate so should not be directly exposed
public:
void calibrate(); // implements Calibration::calibrate
};
class Manual : public Calibration {
public:
void calibrate(); // implements Calibration::calibrate
};
//Implement functions
void Calibration::init()
{
calibrate(); //calls calibrate function implemented by subclasses
}
//Automatic uses calibrate to call config to keep Calibration's interface simple
void Automatic::calibrate()
{
std::cout << "called Automatic::calibrate" << std::endl;
config();
}
void Automatic::config()
{
std::cout << "called Automatic::config" << std::endl;
}
//Manual uses calibrate to do whatever manual needs to do to calibrate
void Manual::calibrate()
{
std::cout << "called Manual::calibrate" << std::endl;
}
//demonstration
int main()
{
Automatic a;
a.init(); // can directly init an Automatic.
// This will call Calibrate::init, which will then call the correct calibrate
Manual m;
m.init(); // or a manual
Calibration * c = new Automatic();
c->init(); // magic of polymorphism calls correct calibrate
delete c;
c = new Manual();
c->init();
delete c;
}