Virtual Table and _vptr in Multiple Inheritance

Discussion in 'C++' started by Mridula, Mar 21, 2009.

  1. Mridula

    Mridula New Member

    Joined:
    Mar 5, 2008
    Messages:
    316
    Likes Received:
    19
    Trophy Points:
    0
    Occupation:
    S/w proffessional
    Location:
    Bangalore

    Introduction



    This article talks about how Virtual table and _vptr looks in case of simple Multiple Inheritance

    Background



    In Multiple Inheritance, the Derived class contains the _vptr of all it's Base classes.

    Lets see the below example, where-in, derived class i.e. Derive is derived from
    Base1, Base2 & Base3 classes.

    Here is the example code and it's output for Simple Multiple Inheritance

    The code



    Code:
    #include<iostream.h>
    
    class Base1 
    {
      public:
        int a;
    
        virtual void func1() { cout << "Base1::func1()" << endl; }
        virtual void func2() { cout << "Base1::func2()" << endl; }
    
    };
    
    class Base2 {
    
      public:
        virtual void func1() { cout << "Base2::func1()" << endl; }
        virtual void func2() { cout << "Base2::func2()" << endl; }
    };
    
    class Base3 {
      public:
        virtual void func1() { cout << "Base3::func1()" << endl; }
        virtual void func2() { cout << "Base3::func2()" << endl; }
    };
    
    class Derive : public Base1, public Base2, public Base3 
    {
      public:
    
        int b;
    
        virtual void disp1() 
        { 
          cout << "Derive::disp1" << endl; 
        }
        virtual void Fnc() 
        { 
          cout << "Derive::disp2" << endl; 
        }
    
    };
    
    typedef void(*function)(void);
    
    int main()
    {
      Derive obj;
      function func = NULL;
      
      //Size contains the _vptr of all it's base classes and Base class data and it's own  
      //Data
      cout<<"Size of obj = "<<sizeof(obj)<<endl;
     
      // calling 1st virtual function of Base1
      func = (function)*((int*)*(int*)((int*)&obj+0)+0);
      func();
    
      // calling 2nd virtual function of Base1
      func = (function)*((int*)*(int*)((int*)&obj+0)+1);
      func();
    
      //Next location contains the Base1's data, lets change it and check the o/p
      int* pInt = (int*)&obj+1;
      *(pInt+0) = 30;
      cout<<"Base1 class fields: a =" << obj.a <<endl;
      
      // calling 1st virtual function of Drive
      func = (function)*((int*)*(int*)((int*)&obj+0)+2);
      func();
    
      // calling 2nd virtual function of Drive
      func = (function)*((int*)*(int*)((int*)&obj+0)+3);
      func();
    
      // calling 1st virtual function of Base2
      func = (function)*((int*)*(int*)((int*)&obj+2)+0);
      func();
    
      // calling 2nd virtual function of Base2
      func = (function)*((int*)*(int*)((int*)&obj+2)+1);
      func();
    
      // calling 1st virtual function of Base3
      func = (function)*((int*)*(int*)((int*)&obj+3)+0);
      func();
    
      // calling 2nd virtual function of Base3
      func = (function)*((int*)*(int*)((int*)&obj+3)+1);
      func();
    
      //At the end, it contains it's own data i.e. Derive classes data, lets change it and   
      //check the o/p
      pInt = (int*)&obj+4;
      *(pInt+0) = 100;
      cout<<"Derive class fields: b =" << obj.b <<endl;
    
      return 0;
    }
    
    output
    ---------
    
    Size of obj = 20
    Base1::func1()
    Base1::func2()
    Base1 class fields: a =30
    Derive::disp1
    Derive::disp2
    Base2::func1()
    Base2::func2()
    Base3::func1()
    Base3::func2()
    Derive class fields: b =100
    
    
    Here is the diagram that shows _vptr s of all Derive's Base classes:

    [​IMG]

    And as seen in the diagram, class Derive, contains the _vptr of all it's base classes.
    Also, you can notice that, Derive class's only methods will be listed after it's first Base class's virtual methods i.e. class Base1

    Here is the diagram that shows the complete picture of Derive class object i.e. obj in the code.

    [​IMG]

    Wherein, it initially contains the first base class's i.e Base1's _vptr and it's data i.e. int a. Then contains the next base class's i.e. Base2 _vptr, then it's data (if any). Next, it's third base class i.e. Base3 class's _vptr and it's data.
    Then at the end it contains it's own data i.e Derive class's data i.e. int b here the example.

    In next artcile, I will talk about how Virtul Table and _vptr looks, in case of Diamnd Problem and it's solution in Multiple Inheritance.
     
    Last edited by a moderator: Jan 21, 2017
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Article of the month competition nomination started here
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice