8/25/09

When is virtual inheritance needed?

Multiple inheritance is a powerful and useful feature in C++, but it can lead to a problem known as the DDD or "Deadly Diamond of Derivation", as in this case:
class ElectricAppliance{ int voltage, int Hertz ; public: //...constructor and other useful methods int getVoltage () const { return voltage; } int getHertz() const {return Hertz; } };
class Radio : public ElectricAppliance {...}; class Tape : public ElectricAppliance {...};
class RadioTape: public Radio, public Tape { //multiple inheritance //... }; void main() {
RadioTape rt;
int voltage = rt.getVoltage(); //compilation Error -- ambiguous //call; //two copies getVoltage() exist in rt: //one from Radio and one from Tape. //Also: which voltage value should be //returned? }//end main()
The problem is clear: rt is derived simultaneously from two base classes, each having its own copy of the methods and data members of ElecctricAppliance. As a result, rt has two copies of ElectricAppliance. This is the DDD. However, giving up multiple inheritance will lead to a design compromise. So in cases where reduplication of data and methods from a common base class is undesirable, virtual inheritance should be used:
class Radio : virtual public ElectricAppliance {...}; class Tape : virtual public ElectricAppliance {...}; class RadioTape: public Radio, public Tape { //multiple inheritance };
As a result, class RadioTape contains a single instance of ElectricAppliance shared by Radio and Tape, so there are no ambiguities, no memory waste, and no need to give up the powerful tool of multiple inheritance:
void main() { RadioTape rt; int voltage = rt.getVoltage(); //now OK }//end main()

No comments: