Skip to main content

Virtual Base Class / Diamond Problem in C++


Virtual Base Class / Diamond Problem in C++

Ø  When we try to implement multiple inheritance or multipath inheritance multiple base classes are inherited that are also inherited from same super-base class.
§  An element of ambiguity can be introduced into a C++ program when multiple base classes are inherited.
Ø  For example: -

#include<iostream>
using namespace std;

class Base
{
      public:
             int a;
};

class D1:public Base    // D1 inherits Base
{
      public:
              int b;
};

class D2:public Base    // D2 inherits Base
{
      public:
             int c;
};

class D3:public D1, public D2          //D3 inherits D1 and D2
{                                      //So there are 2 copies of Base in D3
      public:
             int total;               
};

int main()
{
    D3 ob;
    ob.a=25;     // this is ambiguious, which a? , since a is in D2 as well as in D3, and D3 inherits from both
    ob.b=50;
    ob.c=75;
   
    ob.total=ob.a + ob.b + ob.c;        // a ambiguous
   
    cout<<ob.a <<"\t"<<ob.b<<"\t"<<ob.c<<"\t"<<ob.total<<"\n";
   
    return 0;
}
        

Compilation Error:

As both D1 and D2 inherit Base, they have copies of Base. However D3 inherits both D1 and D2. This means that there are two copies of Base present in an object of type D3. Therefore, in an expression like

ob.a=25;
which a is being referred to the one in D1 or the one in D2? Because there are two copies of Base present in the object ob, there are two ob.a’s. Thus, the statement is inherently ambiguous.

This is also known as Diamond Problem in C++.
Virtual Base Class / Diamond Problem
There are two ways to resolve this problem.
1.      To apply scope resolution to a and manually select one a.
2.      By using virtual keyword before the base class’ name when it is inherited.

Way 1: - To apply scope resolution(::) to a and manually select one a.
Need some changes in main() function. Rest of the program remains same.
 int main()
{
    D3 ob;
    Ob.D1::a=25;    
    ob.b=50;
    ob.c=75;
   
    ob.total=ob.D1::a + ob.b + ob.c;       
   
    cout<<ob.D1::a <<"\t"<<ob.b<<"\t"<<ob.c<<"\t"<<ob.total<<"\n";
   
    return 0;
}


Way 2: - using virtual keyword before the base class’ name when it is inherited

By using virtual keyword before the base class’ name when it is inherited in the program D3 contains only one copy of Base.

#include<iostream>
using namespace std;

class Base
{
      public:
             int a;
};

class D1: virtual public Base   
{
      public:
              int b;
};

class D2: virtual public Base   
{
      public:
             int c;
};

class D3:public D1, public D2     // this time, there is only one copy of Base    
{                                     
      public:
             int total;               
};

int main()
{
    D3 ob;
    ob.a=25;    
    ob.b=50;
    ob.c=75;
   
    ob.total=ob.a + ob.b + ob.c;       
   
    cout<<ob.a <<"\t"<<ob.b<<"\t"<<ob.c<<"\t"<<ob.total<<"\n";
   
    return 0;
}

   



Comments

Popular posts from this blog

Use Case Diagram for Online Book Store

Online Movie Ticket Booking Sequence Diagram

Linear search & Binary search using Template

Write a program to search an element from a list. Give user the option to perform Linear or Binary search. Use Template functions. #include<iostream> using namespace std; template <class T> void Lsearch(T *a, T item, int n) { int z=0; for(int i=0;i<n;i++) { if(a[i]== item) { z=1; cout<<"\n Item found at position = "<<i+1<<"\n\n"; } else if(z!=1) { z=0; } } if(z==0) cout<<"\n Item not found in the list\n\n"; } template <class T> void Bsearch(T *a, T item, int n) { int beg=0,end=n-1; int mid=beg+end/2; while((a[mid]!=item) && (n>0)) { if(item>a[mid]) beg=mid; else end=mid; mid=(beg+end)/2; n--; } if(a[mid]==item) cout<<"\n Item found at position = "<<mid+1<<"\n\n"; else cout<<"\n Item not found in the list\n\n"; } void main() { int iarr[10] = {2,42,56,86,87,99,323,546,767,886};