C++多重继承虚表的内存分布

接前面虚表的内存分布,今天重点看多重继承的虚表内存分布,简单的说,继承几个类便有几个虚表,如下代码

class Drive : public Base1, public Base2, public Base3 {
public:
    virtual void fd() { cout << "Drive::fd" << endl; }
    virtual void gd() { cout << "Drive::gd" << endl; }
};

则虚表有3个,如下图所示:

添加更多的测试代码:

// trytest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <WTypes.h>
#include < iostream >

using namespace std;

class Base1 {
    virtual void f() { cout << "Base1::f" << endl; }
    virtual void g() { cout << "Base1::g" << endl; }
};

class Base2 {
    virtual void f() { cout << "Base2::f" << endl; }
    virtual void g() { cout << "Base2::g" << endl; }
};

class Base3 {
    virtual void f() { cout << "Base3::f" << endl; }
    virtual void g() { cout << "Base3::g" << endl; }
};

class Drive : public Base1, public Base2, public Base3 {
public:
    virtual void fd() { cout << "Drive::fd" << endl; }
    virtual void gd() { cout << "Drive::gd" << endl; }
};

typedef void(*Fun)(void);

int main() {
    Drive objDrive;
    cout << "Size is = " << sizeof(objDrive) << endl; 

    Fun pFun = NULL;

    cout<<"sizeof(int)="<<sizeof(int)<<endl;
    cout<<"sizeof(int*)="<<sizeof(int*)<<endl;

    // 调用Base1的第一个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 0);
    pFun();
    // 调用Base1的第二个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 1);
    pFun();
    cout << "Address of virtual pointer 1 " << (int*)(&objDrive + 0) << endl;
    cout << "Value at virtual pointer i.e. Address of virtual table " 
        << (int*)*(int*)((int*)&objDrive + 0) << endl;
    cout << "Information about VTable 1" << endl; 
    cout << "Value at 1st entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 0) << endl; 
    cout << "Value at 2nd entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 1) << endl; 



    // 调用Base2的第一个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 1) + 0);
    pFun();
    // 调用Base2的第二个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 1) + 1);
    pFun();
    cout << "Address of virtual pointer 2 " << (int*)((int*)&objDrive + 1) << endl;
    cout << "Value at virtual pointer i.e. Address of virtual table " 
        << (int*)*(int*)((int*)&objDrive + 1) << endl;
    cout << "Information about VTable 2" << endl; 
    cout << "Value at 1st entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 1) + 0) << endl; 
    cout << "Value at 2nd entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 1) + 1) << endl; 

    // 调用Base3的第一个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 2) + 0);
    pFun();
    // 调用Base3的第二个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 2) + 1);
    pFun();
    cout << "Address of virtual pointer 3 " << (int*)((int*)&objDrive + 2) << endl;
    cout << "Value at virtual pointer i.e. Address of virtual table " 
        << (int*)*(int*)((int*)&objDrive + 2) << endl;
    cout << "Information about VTable 3" << endl; 
    cout << "Value at 1st entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 2) + 0) << endl; 
    cout << "Value at 2nd entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 2) + 1) << endl; 

    // 调用派生类的第一个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 2);
    pFun();
    // 调用派生类的第二个虚函数
    pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 3);
    pFun();
    cout << "Value at 3rd entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 2) << endl; 
    cout << "Value at 4th entry of VTable " 
        << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 3) << endl; 

 
    //明确多重继承中虚函数的内存位置
    cout <<"Address at 1st entry of VTable "
        << (int*)*((int*)&objDrive + 0) + 0 << endl; 

    cout <<"Address at 2nd entry of VTable "
        << (int*)*((int*)&objDrive + 0) + 1 << endl; 

    cout <<"Address at 3rd entry of VTable "
        << (int*)*((int*)&objDrive + 0) + 2 << endl; 

    cout <<"Address at 4th entry of VTable "
        << (int*)*((int*)&objDrive + 0) + 3 << endl; 

    pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 0);
    pFun();

    pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 1);
    pFun();

    pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 2);
    pFun();

    pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 3);
    pFun();


    return 0;
}

内存分布如下所示:

原文地址:https://www.cnblogs.com/luhouxiang/p/3215343.html