C & C++ Programming - Diamond Inheritence
            
            
                //////////////////////////////////////////////////////////////////////////////////////////////////
                // Programmer: SG //
                // Description: //
                //////////////////////////////////////////////////////////////////////////////////////////////////
                
                #include "stdafx.h"
                #include "iostream"
                using namespace std;
                
                //////////////////////////////////////////////////////////////////////////////////////////////////
                // CBase
                class CBase
                {
                private:
                int m_nA;
                
                public:
                
                CBase()
                
                {
                
                cout << __FUNCTION__ << " No Args" << endl;
                m_nA = -1;
                };
                
                CBase(int x)
                
                {
                
                cout << __FUNCTION__ << " Single Args" << endl;
                m_nA=x;
                };
                
                void getA()
                
                {
                cout << "\n Enter value of A = ";
                cin >> m_nA;
                }
                
                void putA()
                
                {
                cout<<"\n A = " << m_nA;
                }
                };
                
                //////////////////////////////////////////////////////////////////////////////////////////////////
                // CDeriveVirtualOne
                class CDeriveVirtualOne
                : virtual public CBase
                {
                private:
                int m_nB;
                
                public:
                CDeriveVirtualOne()
                
                : CBase(10)
                {
                cout << __FUNCTION__ << " No Args" << endl;
                }
                
                CDeriveVirtualOne(int x)
                
                {
                cout << __FUNCTION__ << endl;
                }
                
                void getB()
                
                {
                cout << "\n Enter value of B = ";
                cin >> m_nB;
                }
                
                void putB()
                
                {
                cout<<"\n B = " << m_nB;
                }
                };
                
                //////////////////////////////////////////////////////////////////////////////////////////////////
                // CDeriveVirtualTwo
                class CDeriveVirtualTwo
                : public virtual CBase
                {
                private:
                int m_nC;
                
                public:
                CDeriveVirtualTwo(int x=0)
                
                : CBase(x)
                {
                cout << __FUNCTION__ << endl;
                }
                
                void getC()
                {
                cout << "\n Enter value of C = ";
                cin >> m_nC;
                }
                
                void putC()
                
                {
                cout<<"\n C = " << m_nC;
                }
                };
                
                //////////////////////////////////////////////////////////////////////////////////////////////////
                // CDerived
                class CDerived
                : public CDeriveVirtualOne
                , public CDeriveVirtualTwo
                {
                private: int m_nD;
                
                public:
                CDerived(int x)
                
                : CDeriveVirtualOne(x)
                , CDeriveVirtualTwo(x)
                {
                cout << __FUNCTION__ << endl;
                }
                
                void getD()
                
                {
                cout << "\n Enter value of D = "; cin >> m_nD;
                }
                
                void putD()
                
                {
                cout<<"\n D = " << m_nD << endl;
                }
                };
                
                //////////////////////////////////////////////////////////////////////////////////////////////////
                // Driver Function
                void main()
                {
                // This will invoke the following in the described order
                // 1. Base class constructor
                // 2. VirtualOne class constructor
                // 3. VirtualTwo class constructor
                // 4. Derived class Constructor
                CDerived obj(5);
                
                cout << "size of = " << sizeof(obj) << endl;
                
                obj.getA();
                obj.getB();
                obj.getC();
                obj.getD();
                
                obj.putA();
                obj.putB();
                obj.putC();
                obj.putD();
                
                // Derive class constructor (with any args) always call default constructor of base
                call
                
                // unless specified.
                CDeriveVirtualOne obj(5);
                }