C ++修改基类而不影响继承的类

时间:2017-12-01 14:20:59

标签: c++ inheritance

我有一个基类,它由不同项目中的许多其他类继承。一个项目需要添加基类。不幸的是,当我尝试编译所有其他项目时,这会引发错误。

基类:

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个继承类中使用新函数。

2 个答案:

答案 0 :(得分:2)

解决问题的一个简单方法就是这样:

virtual void midiProgramChangeReceived(unsigned char) { }

这样,没有其他派生类必须实现它。但是,将方法放在派生类中总是更好。

答案 1 :(得分:1)

如果将no-op实现添加到基类,则不需要在每个单独的项目中添加它。 (可选)包含一个断言警报,如果它被调用而没有被正确的实现覆盖:

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

第二个选项是将#tdef代码隐藏在不需要它的项目中。在编译时为需要它的项目启用它: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的一个成功改进。