and I am facing a trouble with polymorphic classes and inheritance.
I have a parent class
//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();
}
and I have two children
//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();
}
How I correct call Manual::calibrate and Automatic::config from Calibrate::init() ?
I have tried:
void Calibrate::init(){
Automatic::config();
}
but the error I got was:
error: no member function declared in class 'automatic'
In object oriented programming this issue is addressed best with member function overloading.
Make the Calibrate::init() virtual
virtual void init();
overload the init method in each subclass, and call the child specific methods in each.
class Manual : public Calibration {
public:
void init();
void calibrate();
}
Manual::init()
{
this->calibrate();
}
The simplest route is to have only one function, calibrate that is virtual and overridden by subclasses of Calibration.
For this I prefer and demonstrate a pure virtual function. The compiler will catch the mistake if a subclass does not implement pure virtual calibration. If pure virtual is not the right choice for your class hierarchy, define the children's calibrate methods as void calibrate() override; to catch future mistakes should the calibrate method be changed and no longer match.
There is a strong case to be made for making calibrate a protected function so that it cannot be called directly, forcing Calibration's users to use the init function and ensuring the device is fully initialized.
To keep the following code clean, I have removed the unused functions.
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With