THIS POST IS BASICALLY EXPLAINING THE SPECIAL PROBLEMS IN INHERITANCE..will keep updating
The diamond problem
The diamond problem occurs when two superclasses of a class have a common base class. For example, in the following diagram, the TA class gets two copies of all attributes of Person class, this causes ambiguities.
#include<iostream> using namespace std; class Person { // Data members of person public : Person( int x) { cout << "Person::Person(int ) called" << endl; } }; class Faculty : public Person { // data members of Faculty public : Faculty( int x):Person(x) { cout<< "Faculty::Faculty(int ) called" << endl; } }; class Student : public Person { // data members of Student public : Student( int x):Person(x) { cout<< "Student::Student(int ) called" << endl; } }; class TA : public Faculty, public Student { public : TA( int x):Student(x), Faculty(x) { cout<< "TA::TA(int ) called" << endl; } }; int main() { TA ta1(30); }
OUTPUT:Person::Person(int ) called Faculty::Faculty(int ) called Person::Person(int ) called Student::Student(int ) called TA::TA(int ) called
In the above program, constructor of ‘Person’ is called two times. Destructor of ‘Person’ will also be called two times when object ‘ta1′ is destructed. So object ‘ta1′ has two copies of all members of ‘Person’, this causes ambiguities. The solution to this problem is ‘virtual’ keyword. We make the classes ‘Faculty’ and ‘Student’ as virtual base classes to avoid two copies of ‘Person’ in ‘TA’ class. For example, consider the following program.
Delegating to a sister classA powerful technique that arises from using virtual inheritance is to delegate a method from a class in another class by using a common abstract base class. This is also called cross delegation. Let's assume we have a similar scenario like in the diamond example, with small changes. Suppose the write() method in transmitter class needs to access the read() method from receiver for the radio to work (this is kind of a weird behavior, but let's take it for the sake of illustration) :class storable { public: storable(const char*); virtual void read()=0; //this becomes pure virtual making storable an abstract virtual void write(); //class virtual ~storable(); private: .... } class transmitter: public virtual storable { public: void write() { read(); .... } } class receiver: public virtual storable { public: void read(); } class radio: public transmitter, public receiver { public: ... } int main() { radio *rad = new radio(); receiver *r1 = rad; transmitter *r2 =rad; rad->write(); r1->write(); r2->write(); return 1; } Because of virtual inheritance, when the write() function from the transmitter class is called, the method read() from the receiver class gets called (as you may have noticed, the transmitter class doesn't have a read() function). In the above hierarchy we can instantiate only the radio class because transmitter and receiver are abstract due to virtual inheritance. |
No comments:
Post a Comment