繁体   English   中英

在 C++ 继承中从 Parent 调用 Child 方法的最佳方法

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

我在多态类和继承方面遇到了麻烦。

我有一个父类

//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();
}

我如何从Calibrate::init()正确调用Manual::calibrateAutomatic::config

我试过:

void Calibrate::init(){
 Automatic::config();
}

但我得到的错误是:

错误:没有在类“自动”中声明成员函数

在面向对象的编程中,这个问题最好通过成员函数重载来解决。

使Calibrate::init()虚拟

virtual void init();

在每个子类中重载 init 方法,并在每个子类中调用子类特定的方法。

class Manual : public Calibration {
public:
void init();
void calibrate();
}

Manual::init()
{
   this->calibrate();
}

最简单的方法是只有一个函数, 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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM