Inheritance- IV


The following topics are covered in this section:


Multiple Inheritance

When we have more than one base class for a derived class, we call it as multiple inheritance. So far we have only seen the case where a derived class has one base class. In this section we will deal with the features and problems associated with multiple inheritance. Some programmers advise against the use of multiple inheritance. In fact Java does not permit multiple inheritance.

For a basic explanation about multiple inheritance, assume that you have created two classes called ‘bacteria’ and ‘virus’ to model the two different life forms. Now, maybe you discover a new life form that has the features of both bacteria and virus. Instead of creating a new class with all the properties again you can simply derive a new class from both bacteria and virus (hence bacteria and virus will be the two base classes).

Let’s call the derived class as ‘crossbreed’. The program is written below:

class bacteria
{protected:
    int x;
public:
bacteria( )
{
cout<<endl<<"Bacteria constructor";
x=1;
}
void disp( )
{
cout<<endl<<"Value of x for bacteria is : "<<x;
}
};
class virus
{protected:
    int x;
public:
virus( )
{
cout<<endl<<"Virus constructor";
x=100;
}
void disp( )
{
cout<<endl<<"Value of x for virus is : "<<x;
}
};
class crossbreed:public bacteria, public virus
{public:
crossbreed( )
{
bacteria::x=10;
cout<<endl<<"This is the crossbreed of bacteria and virus";
}`
void disp( )
{
cout<<endl<<"This is crossbreed disp function.";
}
};
int main( )
{crossbreed bv;
bv.bacteria::disp( );
bv.disp( );
return 0;
}

The output will be:

Bacteria constructor
Virus constructor
This is the crossbreed of bacteria and virus
Value of x for bacteria is : 10
This is crossbreed disp function.

The main points to be noted are:

  1. Each of the three classes have their own void disp ( ) function. The two base classes have their own protected member data ‘x’. Hence the derived class ‘crossbreed’ will have access to both the member data. To specifically access one of the member data, you have to make use of the scope resolution operator to specify which class’ member data ‘x’ you want to access. For example:
    bacteria::x=10;
  2. Take note of the order of execution of the constructors. The bacteria class constructor is executed first, followed by virus and finally the derived class constructor is executed. Why is it that bacteria constructor executes first before virus? This is because we have specified the class bacteria first in the derived class:
    class crossbreed:public bacteria, public virus
  3. Destructors will be invoked in exactly the reverse order.
  4. Both base classes have the function disp ( ) and to call one of them using an object of the derived class we have to use the scope resolution operator.
    bv.bacteria::disp( );
  5. You can make use of virtual functions to override the base class functions by declaring the disp ( ) function as virtual in both the base classes. Let’s assume that the disp ( ) function in both bacteria and virus class are made virtual. Let’s also assume that we haven’t written a disp ( ) function for the derived class crossbreed. Now if you create an object of type crossbreed and try to execute the disp ( ) function of the crossbreed class, what will happen? If crossbreed were derived from one base class then the base class virtual function would have been executed. But in this case there are two base classes and the compiler will produce an error (because it won’t know which base class function to execute). This is one of the problems with multiple inheritance.


Virtual Base Class

There is another problem associated with multiple inheritance. There is a good chance that your derived class can have more than one copy of the base class. Consider three classes as shown in the figure below:

The following diagram is better suited to explain the problem inherent in multiple inheritance.

The problem with the above form of inheritance is that both base1 and base2 will have a copy of the class ‘mainbase’. When the class ‘derived’ is obtained from these two classes, it will end up with two copies of ‘mainbase’. If mainbase had a member data called ‘count’, then ‘derived’ class cannot access the member ‘count’ by saying:

count=1;

The ‘derived’ class has to specify which copy of ‘count’ it wants to access using the scope resolution operator.

base1::count=1;

Mostly you wouldn’t want such a case and so C++ introduces virtual base class to prevent the ‘derived’ class from obtaining two copies of the same class. You can specify in the derived class that the base classes are ‘virtual’. Check out the example below:

#include <iostream.h>
class mainbase
{ protected:
    int count;
public:
mainbase( )
{
count=0;
}
};
class base1 : virtual public mainbase
{ };
class base2 : virtual public mainbase
{ };
class derived : public base1, public base2
{public:
void set( )
{
count=1;
cout<<endl<<"The count is : "<<count;
}
};
int main( )
{ derived d;
d.set( );
return 0;
}

The output is:

The count is : 1

Now there is no problem when referring to the variable ‘count’. Though the two classes ‘base1’ and ‘base2’ are inheriting ‘mainbase’ as virtual, both of them will individually have their own copy of ‘count’. The ‘virtual’ effect occurs only when some other class uses these two classes as its base class. In that case that derived class will have only one copy of ‘mainbase’.

Alternative Representation of Inheritance:

In all the earlier figures for inheritance we have used a downward pointing arrow to denote inheritance. The following representation is also used for inheritance:

In this case the arrow points from the subclass to the superclass. This also means that the class or RacingCars is inherited (or derived) from the GeneralCars class. Do not get confused with the two methods of representing inheritance.


Go back to the Contents Page 2


Copyright © 2004 Sethu Subramanian All rights reserved.