测试代码:

#include <iostream>

using namespace std;
struct A{
    long long a = 10;
    virtual void fa(){
        cout << "A::fa()\n";
    }
    virtual void faa(){
        cout << "A::faa()\n";
    }
};
// 如果是虚继承,虚基类被放在了派生类的后面,每个基类都有自己的虚函数表指针存储单元,如果虚基类没有虚函数,则虚基类的虚函数表指针为 0 
// 如果是非虚继承,基类在派生类的前面,每个基类都有自己的虚函数表指针存储单元,除了第一个基类(派生类与第一个基类共用一个存储单元)
struct E: virtual A{
    long long e = 2;
    virtual void fa(){
        cout << "E::fa()\n";
    }
    virtual void fe(){
        cout << "E::fe()\n";
    }
};
int main()
{
    typedef void(*FUNC)();
    E e;
    cout << sizeof(e) << endl;
    
    long long* addr = (long long*)&e;
    long long* vfptre = (long long*)*(addr + 0);
    int eval = (int)*(addr + 1);
    cout << eval << endl;
    long long* vfptra = (long long*)*(addr + 2);
    int aval = (int)*(addr + 3);
    cout << aval << endl;
    
    cout << "---------------\n";
    long long* faptr = (long long*)*(vfptre + 0);
    (FUNC(faptr))();
    long long* feptr = (long long*)*(vfptre + 1);
    (FUNC(feptr))();
    cout << "---------------\n";
    long long* faptra = (long long*)*(vfptra + 0);
    // (FUNC(faptra))(); // 如果虚基类的虚函数被重写,此处则无法再如此执行
    long long* faaptra = (long long*)*(vfptra + 1);
    (FUNC(faaptra))(); 
	return 0;
}

输出:

32
2
10
---------------
E::fa()
E::fe()
---------------
A::faa()
#include <iostream>

using namespace std;

class B
{
public:
	B() : _ib(10), _cb('0') {}

	virtual void f()
	{
		cout << "B::f()" << endl;
	}

	virtual void Bf()
	{
		cout << "B::Bf()" << endl;
	}

private:
	long long _ib;
	char _cb;
};

class B1 : virtual public B
{
public:
	B1() : _ib1(100), _cb1('1') {}

	virtual void f()
	{
		cout << "B1::f()" << endl;
	}

#if 1
	virtual void f1()
	{
		cout << "B1::f1()" << endl;
	}
	virtual void Bf1()
	{
		cout << "B1::Bf1()" << endl;
	}
#endif

private:
	long long _ib1;
	char _cb1;
};

class B2 : virtual public B
{
public:
	B2() : _ib2(1000), _cb2('2') {}

	virtual void f()
	{
		cout << "B2::f()" << endl;
	}
#if 1
	virtual void f2()
	{
		cout << "B2::f2()" << endl;
	}
	virtual void Bf2()
	{
		cout << "B2::Bf2()" << endl;
	}
#endif
private:
	long long _ib2;
	char _cb2;
};

class D : public B1, public B2
{
public:
	D() : _id(10000), _cd('3') {}

	virtual void f()
	{
		cout << "D::f()" << endl;
	}

#if 1
	virtual void f1()
	{
		cout << "D::f1()" << endl;
	}
	virtual void f2()
	{
		cout << "D::f2()" << endl;
	}

	virtual void Df()
	{
		cout << "D::Df()" << endl;
	}
#endif
private:
	long long _id;
	char _cd;
};

int main()
{
    
	// Test_3
	D d;
	long long*dAddress = (long long*)&d;
	typedef void(*FUNC)();
	cout << sizeof(d) << endl;

	// 1. 获取对象的内存布局信息
	// 虚表地址一
	long long*vtptr1 = (long long*)*(dAddress + 0);
	int base1mem1 = (int)*(dAddress + 1);
	int base1mem2 = (int)*(dAddress + 2);

	long long*vtptr2 = (long long*)*(dAddress + 3);
	int base2mem1 = (int)*(dAddress + 4);
	int base2mem2 = (int)*(dAddress + 5);

// 	long long*vtptr3 = (long long*)*(dAddress + 6);
// 	int base3mem = (int)*(dAddress + 3);

	int Dmem1 = (int)*(dAddress + 6);
	int Dmem2 = (int)*(dAddress + 7);

	long long*vtptr3 = (long long*)*(dAddress + 8);
	int Bmem1 = (int)*(dAddress + 9);
	int Bmem2 = (int)*(dAddress + 10);

// 	int imem1 = (int)*(dAddress + 7);
	cout << base1mem1 << endl;
	cout << base1mem2 << endl;
	cout << base2mem1 << endl;
	cout << base2mem2 << endl;
	cout << Dmem1 << endl;
	cout << Dmem2 << endl;
	cout << Bmem1 << endl;
	cout << Bmem2 << endl;
	cout << "----------------\n";

	// 2. 输出对象的内存布局信息
	long long*pBase1Func1 = (long long*)*(vtptr1 + 0);
	long long*pBase1Func2 = (long long*)*(vtptr1 + 1);
	long long*pBase1Func3 = (long long*)*(vtptr1 + 2);
	long long*pBase1Func4 = (long long*)*(vtptr1 + 3);
	long long*pBase1Func5 = (long long*)*(vtptr1 + 4);
	(FUNC(pBase1Func1))();
	(FUNC(pBase1Func2))();
	(FUNC(pBase1Func3))();
	(FUNC(pBase1Func4))();
	(FUNC(pBase1Func5))();
	cout << "----------------\n";
	// .... 后面省略若干输出内容,可自行补充
	long long*pBase2Func1 = (long long*)*(vtptr2 + 0);
	long long*pBase2Func2 = (long long*)*(vtptr2 + 1);
	long long*pBase2Func3 = (long long*)*(vtptr2 + 2);
	(FUNC(pBase2Func1))();
	(FUNC(pBase2Func2))();
	(FUNC(pBase2Func3))();
	cout << "----------------\n";
	
	long long*pBaseFunc1 = (long long*)*(vtptr3 + 0);
	long long*pBaseFunc2 = (long long*)*(vtptr3 + 1);
// 	(FUNC(pBaseFunc1))();
	(FUNC(pBaseFunc2))();
	cout << "----------------\n";
	
	B* pb = &d;
	pb->f();
	pb->Bf();
	return 0;
}

输出:(64 位操作系统)

88
100
49
1000
50
10000
51
10
48
----------------
D::f()
D::f1()
B1::Bf1()
D::f2()
D::Df()
----------------
D::f()
D::f2()
B2::Bf2()
----------------
B::Bf()
----------------
D::f()
B::Bf()

类似内存布局结构:

内存布局

参考:

浅析C++类的内存布局