C++ 多重继承下的内存布局
1. 多重继承
多重继承示例代码如下:
class Base1 {
public:
    void f0() {}
    virtual void f1() {}
    int a;
};
class Base2 {
public:
    virtual void f2() {}
    int b;
};
class Derived : public Base1, public Base2 {
public:
    void d() {}
    void f2() {}  // override Base2::f2()
    int c;
};
int main() {
    Base2 *b2 = new Base2;
    Derived *d = new Derived;
}
答案是不行
2. top offset
在此,先给出结论:将对象从当前这个类型转换为该对象的实际类型的地址偏移量。
Vtable for Derived
Derived::_ZTV7Derived: 7u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI7Derived)
16    (int (*)(...))Base1::f1
24    (int (*)(...))Derived::f2
32    (int (*)(...))-16
40    (int (*)(...))(& _ZTI7Derived)
48    (int (*)(...))Derived::_ZThn16_N7Derived2f2Evclass Base1和class Base2两个类的虚函数表拼接而成 。因为是多重继承,所以编译器将先继承的那个认为是 主基类(primary base)
在多继承中,当最左边的类中没有虚函数时候,编译器会将第一个有虚函数的基类移到对象的开头,这样对象的开头总是有vptr。
首先看虚函数表的前半部分,如下:
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI7Derived)
16    (int (*)(...))Base1::f1
24    (int (*)(...))Derived::f2
接着看虚函数表的下半部分:
32    (int (*)(...))-16
40    (int (*)(...))(& _ZTI7Derived)
48    (int (*)(...))Derived::_ZThn16_N7Derived2f2Ev偏移值为-16,因为是多重继承,所以class Base1和class Base2类型的指针或者引用都可以指向class Derived对象,那么又是如何调用正确的成员函数呢?
Base2* b2 = new Derived;
b2->f2(); //最终调用Derived::f2();

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号