2016-06-16 29 views
0

と多形のクラスと継承に問題があります。親のC++継承で子メソッドを呼び出すのに最適な方法

私は、親クラスに

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

を持っていると私はCalibrate::init()からManual::calibrateAutomatic::configを呼び出す修正どのように2人の子供

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

がありますか?

は、私が試してみました:しかし、私が得たエラーが

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

た:

error: no member function declared in class 'automatic'

+1

自動のヘッダファイルには便利だろう –

+0

誰かがあなたの質問、疑問[リンク](http://stackoverflow.com/questions/357307/how-to-call-a-parent-class-に答えています関数から導出されたクラス関数) – aex

答えて

2

オブジェクト指向プログラミングでは、この問題は、メンバ関数のオーバーロードで最高のアドレス指定されています。

Calibrate::init()仮想

virtual void init(); 

を作るには、各サブクラスでinitメソッドをオーバーロードし、それぞれの子の特定のメソッドを呼び出します。

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

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

適切な解決策。ちょうど、 'init()'は仮想である必要はありません。 – smoku

+0

この方法で私は外部からinitにアクセスできません。私はマニュアルを含むクラスを持っており、m.init()のようにinitをしなければなりません。しかし、それはundefiened参照です – schirrel

0

最も簡単なルートは一つだけの機能、仮想およびCalibrationのサブクラスによってオーバーライドされcalibrateを持つことです。

このためには、私は純粋な仮想関数を好んで実演しています。サブクラスが純粋な仮想calibrationを実装していない場合、コンパイラは間違いをキャッチします。純粋な仮想がクラス階層の正しい選択でない場合は、calibrateメソッドを変更してもはや一致しない場合、子どものcalibrateメソッドをvoid calibrate() override;と定義して将来の間違いをキャッチします。

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; 
} 
関連する問題