虚函数表实现多重继承

Vtable implementation in multiple inheritance

本文关键字:多重继承 实现 函数      更新时间:2023-10-16

我无法弄清楚如何为多重继承创建变量的模式。请看下面的代码:

// 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()
          } 
}

在单继承级别的情况下,它在最后不断向同一个VPTR添加虚函数项,但在多重继承中它是如何决定的?因为它有两个Vptrs

我假设你的代码实际上是伪c++。

但是你的代码是错误的,因为在c++中虚值表是每个类的,而不是每个实例的。每个实例保存一个指向其类的虚函数表的指针。

所以它应该是(当然是伪c++);

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;
}

可以看到,C有两个vtable,一个继承自A,另一个继承自B。第一个扩展了C的所有新的虚函数。

如果C要覆盖sleep(),那么它将建立一个新的VTable:

fn_t C::VTableB[] = { &C::sleep };
C::C()
{
    A::VPtr = C::VTable;
    B::VPtr = C::VTableB;
}