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