MI的C++虚拟表布局(多重继承)

Xia*_*Jun 20 c++ oop

查看以下C++代码

class Base1 {  
public:  
    Base1();  
    virtual ~Base1();  
    virtual void speakClearly();  
    virtual Base1 *clone() const;  
protected:  
    float data_Base1;  
};  

class Base2 {  
public:  
    Base2();  
    virtual ~Base2();  
    virtual void mumble();  
    virtual Base2 *clone() const;  
protected:  
    float data_Base2;  
};  

class Derived : public Base1, public Base2 {  
public:  
    Derived();  
    virtual ~Derived();  
    virtual Derived *clone() const;  
protected:  
    float data_Derived;  
}; 
Run Code Online (Sandbox Code Playgroud)

"C++对象模型内部"4.2表示类Base1,Base2和Derived的虚拟表布局如下: 在此输入图像描述

在此输入图像描述

我的问题是:

Base2::mumbleDerived类的Base1子对象的虚拟表包含.为什么?我知道Derived类与Base1共享这个虚拟表,所以我认为Base2的功能不应该出现在这里.有人可以告诉我为什么?谢谢.

Mat*_* M. 5

首先,我要提醒大家,实现多态的解决方案的设计是标准之外的ABI决策.例如,MSVC和Itanium ABI(后跟gcc,clang,icc,...)有不同的方法来实现它.

有了这个,我认为这是一个查找优化.

每当你有一个Derived对象(或它的一个后代)并查找该mumble成员时,你不需要实际找到Base2子对象,但可以直接从Base1子对象(其地址与Derived子对象一致,因此不涉及算术)进行操作.

  • 更基本的是,编译器在`Base1`的函数后添加了`Derived`的函数,因此两者都可以使用相同的`vtable`.而`mumble`也是`Derived`(通过继承)的函数,而不仅仅是`Base2`.这是一个"优化",但它是基于语言基础的优化.我无法想象任何编译器都没有这样做. (3认同)
  • @ user396672:这不是一个错误.`Derived`和`Base1`有不同的v表,但是`Base1`中的v-ptr可以指向'Derived`表,因为表`Base1`是`Derived`(和`Base1)的前缀. `只会使用它知道的前缀). (2认同)