Reputation: 43
I have a base class that is inherited by many other classes in different projects. One project requires an addition to the base class. Unfortunately this then throws an error when I try to compile all the other projects.
Base class:
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
};
Example inherited class that doesn't need to use new line, but won't compile without it:
#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
Is there any way to add the new code to the base class without having to modify every inherited class that uses it, as I only require the new function for use in 1 inherited class.
Upvotes: 1
Views: 564
Reputation: 1698
An easy fix to your problem would be something like this:
virtual void midiProgramChangeReceived(unsigned char) { }
This way the no other derived classes have to implement it. However it is always better to just put the method in the derived class.
Upvotes: 2
Reputation: 841
If you add the no-op implementation to the base class, you won't need to add it in each of your separate projects. Optionally, include an assertion to alarm if it's ever called without being overridden with a proper implementation:
virtual void midiProgramChangeReceived(unsigned char patchNum) {
assert (!"Unimplemented function, please override with an implementation.");
}
A second option, which hides this function from projects that don't need it, is to #ifdef the code. Enable it at compile-time for the project that needs it: c++ -DENABLE_MINI_PROGRAM_CHANGE_RECEIVED myprog.cpp
. The function won't exist in other projects; thus no one can mistakenly call it, and there's no overhead in virtual method tables. The downside is #ifdef cruft in the code.
#ifdef ENABLE_MIDI_PROGRAM_CHANGE_RECEIVED
virtual void midiProgramChangeReceived(unsigned char patchNum) = 0;
#endif
It's off-topic, but also consider adding override
to virtual methods in the inherited class:
void midiClockStopReceived(void) override {}
This replaces subtle misbehaviors with compile errors if you get the method signature wrong, or if it's ever changed in the future. It's a winning improvement to C++11.
Upvotes: 2