Sunday, August 30, 2015

Problem with Multiple Inheritance in C++ (Diamond Problem)

Multiple Inheritance


 In multiple inheritance a derived class inherits from more than one class.The following figure gives an idea.

                                                   
                                                                   Figure 1

In Figure 1 class D is the derived class and B,C are base classes for it.


Problems with Multiple Inheritance


Consider the following program:
#include<iostream>
using namespace std;

class B{
private:
 int b_var;
public:
   B(){
    b_var=10;
   }
   void display(int b){
    cout<<"Called from B and value is"<<b<<"\n";
   }
};
class C{
private:
 int c_var;
public:
   C(){
    c_var=30;
   }
   void display(int c){
    cout<<"Called from C and value is"<<c<<"\n";
   }
};
class D:public B,public C{

public:
 int d_var;
   D(){
    d_var=40;
   }
 };

int main(){
 D dobject;
 dobject.display(dobject.d_var);
}
 We will get an error: request for member 'display' is ambiguous.
Why this happens? Think!!!

Let's look how the compiler evaluates the above program: 
After creating an object of type D when we call the function display using that object the compiler searches for display function in class D. As the compiler cannot find it then looks to see if any of the base classes have a function named display().
The problem is that 'dobject' actually contains two display() functions: one inherited from class B, and one inherited from class C. Therefore compiler cannot choose between the two and the function call is ambiguous, and will receive a compiler error.

How to solve this problem?

One way is to explicitly mention from which class the method has to be derived. This is known as explicit scoping.
dobject.B::display(dobject.d_var);

And the output is:
Called from B and value is 40

Diamond Problem

Let's complicate things a bit more. Now have a look at the following figure:

                                                                Figure 2

   If the function display is derived from A the program looks like this:
class A{
private:
 int a_var;
public:
   A(){
    a_var=100;
   }
   void display(int a){
    cout<<"Called from A and value is "<<a<<"\n";
   }
};

class B:public A{
private:
 int b_var;
public:
   B(){
    b_var=10;
   }

};
class C:public A{
private:
 int c_var;
public:
   C(){
    c_var=30;
   }

};
class D:public B,public C{

public:
 int d_var;
   D(){
    d_var=40;
   }
 };

int main(){
 D dobject;
 dobject.display(dobject.d_var);

 return 0;
}

The same problem as in the case of multiple inheritance exists and also adds more problems to it.
The compiler doesn't know whether it should have one or two copies of A and how to resolve such ambiguous references. While these problems can be solved using explicit scoping but the maintenance overhead increases.

If we create object of type D then by default compiler ends up creating two copies of class A. As shown in the figure 3.


                                                                        Figure 3

Most of the times we want the compiler to create only one copy of class A.

Is it possible?
Yes, it is possible with the help of virtual base classes.

So let's make some changes to the code and make it work.
class A{
private:
 int a_var;
public:
   A(){
    a_var=100;
   }
   void display(int a){
    cout<<"Called from A and value is "<<a<<"\n";
   }
};

class B:virtual public A{
private:
 int b_var;
public:
   B(){
    b_var=10;
   }

};
class C:virtual public A{
private:
 int c_var;
public:
   C(){
    c_var=30;
   }

};
class D:public B,public C{

public:
 int d_var;
   D(){
    d_var=40;
   }
 };

int main(){
 D dobject;
 dobject.display(dobject.d_var);

 return 0;
}
 And the Output looks like: 
Called from A and value is 40

Here Class A is constructed only once. Before finishing this topic there are few points to be remembered.
First virtual base classes are created before non-virtual base classes, which ensures all bases get created before their derived classes. 

Second, note that the constructors of Classes B and C still have calls to the A's constructor. If we are creating an instance of D, these constructor calls are simply ignored because D is responsible for creating the A, not B or C. However, if we were to create an instance of B or C, the virtual keyword is ignored, those constructor calls would be used, and normal inheritance rules apply.

Third, if a class inherits one or more classes that have virtual parents, the most derived class is responsible for constructing the virtual base class.

Happy Learning....

How Derived classes are constructed in C++

Inheritance is one of the object oriented concept where one object inherits the behavior of another object. This concept is mainly used by the programmers for the purpose of reusing their code.

To know how the order of derived class works lets start with an example:

#include<iostream>
using namespace std;

class Base {
private:
 int base_var;
public:
 Base() {
  base_var = 10;
  cout << "Base is called \n";
 }
};
class Derived: public Base {
private:
 int derived_var;
public:
 Derived() {
  derived_var = 0;
  cout << "Derived is called \n";
 }
};

int main() {
 cout << "Instantiating Base class \n";
 Base b;
 cout << "Instantiating Derived class \n";
 Derived d;

 return 0;
}

In this example the Derived class is derived from Base class, Derived class inherits the public functions and public variables of base class. Figure 1 shows the diagrammatic representation of the classes.
 
                                                                    Figure 1


 If we run the above problem the output looks like this:

Instantiating Base class 
Base is called 
Instantiating Derived class 
Base is called 
Derived is called 

What can we conclude from the output? We can say that when we instantiate a derived class it first calls base part and then derived part. So derived portion consists of two parts: a Base part and a derived part.
When the compiler constructs the derived objects, it does in such a way that it starts with base. Once the base portion is complete it then walks through the inheritance tree and constructs the derived portion. So what actually happens in this example is that the Base portion of Derived is constructed first. Once the Base portion is finished, the Derived portion is constructed. At this point, there are no more derived classes, so we are done.

The construction of the derived classes always starts with base class and then the next derived class and then so on until we reach our actual derived class.