C++ Multipath Inheritance Ambiguity

Advertisements

C++ Multipath Inheritance

A derived class with two base classes and these two base classes have one common base class is called multipath inheritance.

C++ Ambiguity

Ambiguity in C++ occur when a derived class have two base classes and these two base classes have one common base class. Consider the followling figure:


         

Example of, occurrence of C++ ambiguity


       #include<iostream.h>
       #include<conio.h>

       class ClassA
       {
              public:
              int a;
       };

       class ClassB : public ClassA
       {
              public:
              int b;
       };
       class ClassC : public ClassA
       {
              public:
              int c;
       };

       class ClassD : public ClassB, public ClassC
       {
              public:
              int d;
       };

       void main()
       {

			  ClassD obj;

			  //obj.a = 10;                   //Statement 1, Error occur
			  //obj.a = 100;                 //Statement 2, Error occur

			  obj.ClassB::a = 10;        //Statement 3
			  obj.ClassC::a = 100;      //Statement 4

			  obj.b = 20;
			  obj.c = 30;
			  obj.d = 40;

			  cout<< "\n A from ClassB  : "<< obj.ClassB::a;
			  cout<< "\n A from ClassC  : "<< obj.ClassC::a;

			  cout<< "\n B : "<< obj.b;
			  cout<< "\n C : "<< obj.c;
			  cout<< "\n D : "<< obj.d;

	   }

   Output :

              A from ClassB  : 10
              A from ClassC  : 100
              B : 20
              C : 30
              D : 40

In the above example, both ClassB & ClassC inherit ClassA, they both have single copy of ClassA. However ClassD inherit both ClassB & ClassC, therefore ClassD have two copies of ClassA, one from ClassB and another from ClassC.

If we need to access the data member a of ClassA through the object of ClassD, we must specify the path from which a will be accessed, whether it is from ClassB or ClassC, bco'z compiler can't differentiate between two copies of ClassA in ClassD.

There are two ways to avoid c++ ambiguity.

  • Using scope resolution operator
  • Using virtual base class

1.    Avoid ambiguity using scope resolution operator

Using scope resolution operator we can manually specify the path from which data member a will be accessed, as shown in statement 3 and 4, in the above example.


			  obj.ClassB::a = 10;        //Statement 3
			  obj.ClassC::a = 100;      //Statement 4

	 Note : still, there are two copies of ClassA in ClassD.

2.    Avoid ambiguity using virtual base class

To remove multiple copies of ClassA from ClassD, we must inherit ClassA in ClassB and ClassC as virtual class.

Example to avoid ambiguity by making base class as a virtual base class


       #include<iostream.h>
       #include<conio.h>

       class ClassA
       {
              public:
              int a;
       };

       class ClassB : virtual public ClassA
       {
              public:
              int b;
       };
       class ClassC : virtual public ClassA
       {
              public:
              int c;
       };

       class ClassD : public ClassB, public ClassC
       {
              public:
              int d;
       };

       void main()
       {

			  ClassD obj;

			  obj.a = 10;        //Statement 3
			  obj.a = 100;      //Statement 4

			  obj.b = 20;
			  obj.c = 30;
			  obj.d = 40;

			  cout<< "\n A : "<< obj.a;
			  cout<< "\n B : "<< obj.b;
			  cout<< "\n C : "<< obj.c;
			  cout<< "\n D : "<< obj.d;

	   }

   Output :

              A : 100
              B : 20
              C : 30
              D : 40

According to the above example, ClassD have only one copy of ClassA therefore statement 4 will overwrite the value of a, given at statement 3.

Advertisement