Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Way to call Child method from Parent in c++ inheritance

Tags:

c++

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'

like image 486
schirrel Avatar asked Jun 16 '16 19:06

schirrel


2 Answers

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();
}
like image 58
UmNyobe Avatar answered Sep 28 '22 04:09

UmNyobe


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;
}
like image 43
user4581301 Avatar answered Sep 28 '22 04:09

user4581301