2017-12-01 15 views
0

私は異なるプロジェクトの多くの他のクラスによって継承される基本クラスを持っています。 1つのプロジェクトでは、基本クラスに追加が必要です。残念ながら、これは他のすべてのプロジェクトをコンパイルしようとするとエラーになります。C++継承クラスに影響を与えずに基本クラスを変更

基本クラス:

class MidiBase 
{ 
    public: 
    virtual void midiNoteOnReceived(unsigned char note, unsigned char velocity) = 0; 
    virtual void midiNoteOffReceived(unsigned char note) = 0; 
    virtual void midiClockStartReceived(void) = 0; 
    virtual void midiClockStopReceived(void) = 0; 
    virtual void midiSysexStartReceived(void) = 0; 
    virtual void midiSysexDataReceived(unsigned char index, unsigned char data) = 0; 
    virtual void midiSysexStopReceived(void) = 0; 
    virtual void midiSysexWrite(unsigned char data) = 0; 
    virtual void midiControlChangeReceived(unsigned char cc, unsigned char val) = 0; 
    virtual void midiPitchBendReceived(char bend) = 0; 
    virtual void midiProgramChangeReceived(unsigned char patchNum) = 0; //THIS IS THE NEW LINE 
}; 

例は、新しい行を使用する必要はありませんが、それなしでコンパイルされませんクラスを継承した:

#include "Midi.h" 
#include "MidiBase.h" 

class OdyEngine : public MidiBase 
{ 
//variables 
public: 
    static OdyEngine& getInstance() 
    { 
     static OdyEngine instance; // Guaranteed to be destroyed. 
     return instance; 
    } 
protected: 
private: 
    Midi* midi_; 
    //functions 
    public: 
    const Midi* getMidiPtr() const { return midi_; } 
    Midi* getMidiPtr() { return midi_; } 
    void midiControlChangeReceived(unsigned char anlControl_, unsigned char val); 
    void midiNoteOnReceived(unsigned char note, unsigned char velocity); 
    void midiNoteOffReceived(unsigned char note); 
    void midiClockStartReceived(void){} 
    void midiClockStopReceived(void){} 
    void midiSysexStartReceived(void){} 
    void midiSysexDataReceived(unsigned char index, unsigned char data){} 
    void midiSysexStopReceived(void){} 
    void midiSysexWrite(unsigned char data){} 
    void midiChannelChanged(unsigned char channel); 
    void midiPitchBendReceived(char bend); 
    //void midiProgramChangeReceived(unsigned char patchNum){} //WILL NOT COMPILE WITHOUT THIS 
    protected: 
    private: 
    OdyEngine(OdyEngineBase* base); 
    OdyEngine() {} 
    OdyEngine(const OdyEngine &c); 
    ~OdyEngine(); 
    OdyEngine& operator=(const OdyEngine &c); 

}; //OdyEngine 

は新しいを追加する方法はあります私は1つの継承クラスでの使用に新しい関数が必要なので、それを使用するすべての継承クラスを変更することなく、基本クラスにコードを追加できます。他の派生クラスがそれを実装する必要がない

virtual void midiProgramChangeReceived(unsigned char) { } 

この方法:

+0

新しいメソッドのデフォルト実装を提供する必要があるようです。新しいメソッドが呼び出されたときに、既存のすべての派生クラスはどのようにふるまうべきですか?その質問に答えることができない場合は、クラス階層を再考する必要があります。おそらく 'MidiBase'から継承した中間クラスを導入し、新しいメソッドだけを追加します。 –

+0

@paulsoulsbyこれを配列に配置していますか? –

+0

@FrançoisAndrieuxデフォルトの実装は「何もしない」です。私は今のところ、継承されたすべてのクラスを更新すると思います。そのうちの8つしかありません。そのうちの100個(たとえば100個)がある場合は、アプローチを考えていただけでした。 – paulsoulsby

答えて

1

基本クラスにno-op実装を追加した場合、別々のプロジェクトごとに追加する必要はありません。必要に応じて、それは今までに適切な実装で上書きされずに呼ばれていた場合、アラームにアサーションが含まれています。それを必要としないプロジェクトからこの機能を隠し

virtual void midiProgramChangeReceived(unsigned char patchNum) { 
    assert (!"Unimplemented function, please override with an implementation."); 
} 

2番目のオプションは、コードを#ifdefのことです。それを必要とするプロジェクトのコンパイル時に有効にしてください:c++ -DENABLE_MINI_PROGRAM_CHANGE_RECEIVED myprog.cpp。この関数は他のプロジェクトには存在しません。誰もそれを誤って呼び出すことはできません。仮想メソッドテーブルにはオーバーヘッドがありません。欠点は#ifdef cruftです。

#ifdef ENABLE_MIDI_PROGRAM_CHANGE_RECEIVED 
virtual void midiProgramChangeReceived(unsigned char patchNum) = 0; 
#endif 

これは、オフトピックですが、また、継承されたクラスに仮想メソッドにoverrideを追加することを検討:それはだ場合は、メソッドのシグネチャが間違って取得する場合、これはコンパイルエラーと微妙な誤作動を置き換え

void midiClockStopReceived(void) override {} 

、または将来的に変わった。これはC++ 11に勝る改良点です。

2

あなたの問題を簡単に修正はこのようなものになるだろう。ただし、派生クラスにメソッドを配置するほうが常に良いです。

+0

これは良いことです。私はそれをよくやっているかもしれませんが、周りに道があるかどうかを知りたいだけでした。 – paulsoulsby

+0

同じ効果で、より少ない型付け: 'virtual void midiProgramChangeReceived(unsigned char/* patchNum * /){}'変数はオプションです – UKMonkey

関連する問題