Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vtable implementation in multiple inheritance

Tags:

c++

Iam unable to figure out the patten on how vtables are created for multiple inheritance. Please look at following code.

// Iam just providing pseudocode model
class A{
  public:
         Vptr[];    // create function pointer 
         virtual void run(){}
         A(){
             this->Vptr[0] = &A::run; // push virtual function address
         }
}

class B{
  public:
         Vptr[];   // create function pointer
         virtual void sleep(){}
         B(){
             this->Vptr[0] = &B::sleep; // push virtual function address
         }
}

class C : public A, public B{
  public: 
         virtual void run(){}
         virtual void eat(){}
          C(){
             this->A::Vptr[0] = &C::run; // update function address since overrided

             // the question is onto which Vptr does eat() entry is stored?
             // this->A::Vptr[1] = &C::eat() OR this->B::Vptr[1] = &C::eat()
          } 
}

In the case of single inheritance level, it keeps adding the virtual function entries to the same VPTR at the end but in the multiple inheritance how does it decide? because it has 2 Vptrs

like image 574
user3205479 Avatar asked Dec 06 '25 06:12

user3205479


1 Answers

I assume that your code is actually pseudo-C++.

But your code is wrong, because in C++ the vtable is per-class, not per-instance. And each instance holds a pointer to the vtable of its class.

So it would be something like (pseudo-C++, of course);

fn_t A::VTable[] = { &A::run };
fn_t B::VTable[] = { &B::sleep };
fn_t C::VTable[] = { &C::run, &C::eat };

A::A()
{
    A::VPtr = A::VTable;
}
B::B()
{
    B::VPtr = B::VTable;
}
C::C()
{
    A::VPtr = C::VTable;
    B::VPtr = B::VTable;
}

As you can see, C has two VTables, one inherited from A and one from B. The first one is extended with all the new virtual functions of C.

If C were to override sleep(), then it would build a new VTable:

fn_t C::VTableB[] = { &C::sleep };

C::C()
{
    A::VPtr = C::VTable;
    B::VPtr = C::VTableB;
}
like image 88
rodrigo Avatar answered Dec 08 '25 19:12

rodrigo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!