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++.
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
Post a Comment