我有一个基类,它由不同项目中的许多其他类继承。一个项目需要添加基类。不幸的是,当我尝试编译所有其他项目时,这会引发错误。
基类:
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个继承类中使用新函数。
答案 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的一个成功改进。