Diamond Problem in c++:
Scenario 1:
There will be 2 copy of data member of base class, if diamond structure is there.
source code with example:
/* Program: Diamond Problem Author: Alpha Master Date: 29 October 2021 */ //Header File #include<iostream> class A { int x; }; class B: public A { }; class C: public A { }; class D: public B, public C { public: void display() { //std::cout<<"x value:"<<x<<std::endl; } }; int main() { std::cout<<"Diamond Problem"<<std::endl; std::cout<<"Size of D:"<<sizeof(D)<<std::endl; return 0; }
Output:
You can see below that size is 8 that there is 2 copy of ‘x’.
Diamond Problem Size of D:8
Scenario 2:
If we try to access the data member of base class(it has 2 copy) then we will get compiler error.
You can see below example having compilation error due to ambiguity.
source code with example:
/* Program: Diamond Problem Author: Alpha Master Date: 29 October 2021 */ //Header File #include<iostream> class A { int x; }; class B: public A { }; class C: public A { }; class D: public B, public C { public: void display() { std::cout<<"x value:"<<x<<std::endl; } }; int main() { std::cout<<"Diamond Problem"<<std::endl; std::cout<<"Size of D:"<<sizeof(D)<<std::endl; return 0; }
Output:
You can see below compilation error due to ambiguity.
~/Cplus$ g++ diamond.cpp diamond.cpp: In member function ‘void D::display()’: diamond.cpp:28:26: error: reference to ‘x’ is ambiguous std::cout<<"x value:"<<x<<std::endl; ^ diamond.cpp:12:6: note: candidates are: int A::x int x; ^ diamond.cpp:12:6: note: int A::x
Scenario 3:
How to get rid from duplicate copy of data member ?
Solution : virtual inheritance. It internally create Vptr
source code with example:
/* Program: Diamond Problem Author: Alpha Master Date: 29 October 2021 */ //Header File #include<iostream> class A { protected: int x; int y; public: A(int a=0):x(a){} }; class B: virtual public A { }; class C: public virtual A { }; class D: public B, public C { public: void display() { std::cout<<"x value:"<<x<<std::endl; } }; int main() { std::cout<<"Diamond Problem"<<std::endl; std::cout<<"Size of D:"<<sizeof(D)<<std::endl; D d; d.display(); B b; std::cout<<"size of B:"<<sizeof(b)<<std::endl; return 0; }
Output:
You can see below we can access the data member of base class.
size is 24:
8 for data member of base class A(data x and y).
8 for pointer to virtual base B
8 for pointer to virtual base C
size of B:16:
8 for data member of base class A(data x and y).
8 for Vptr
Diamond Problem Size of D:24 x value:0 size of B:16
Scenario 4:
Virtual function is present in base so it has VTable and it all derived class till end of hierarchy will have also VTable.
Each class has one VTable.
source code with example:
/* Program: Diamond Problem Author: Alpha Master Date: 29 October 2021 */ //Header File #include<iostream> class A { protected: int x; int y; public: A(int a=0):x(a){} virtual ~A(){} }; class B: virtual public A { }; class C: public virtual A { }; class D: public B, public C { public: void display() { std::cout<<"x value:"<<x<<std::endl; } }; int main() { std::cout<<"Diamond Problem"<<std::endl; std::cout<<"Size of D:"<<sizeof(D)<<std::endl; D d; d.display(); return 0; }
Output:
You can see below:
size is 32:
8 for data member of base class A(data x and y).
8 for pointer to virtual base B
8 for pointer to virtual base C
8 for Vptr of D(each object has Vptr so that it can access VTable)
Diamond Problem Size of D:32 x value:0