C++ 虚函数表与多态 —— 多重继承的虚函数表 & 内存布局
多重继承的虚函数表会有两个虚表指针,分别指向两个虚函数表,如下代码中的 vptr_s_1、vptr_s_2,Son类继承自 Father 和 Mather 类,并且改写了 Father::func_1 与 Mather::handle_1,这两个虚函数将会存放到两个虚函数表中,Son 新加的 func_4 将会在第一个虚函数表中:
1 #include <iostream> 2 using namespace std; 3 4 class Father 5 { 6 public: 7 virtual void func_1() { cout << "Father::func_1" << endl; } 8 virtual void func_2() { cout << "Father::func_2" << endl; } 9 virtual void func_3() { cout << "Father::func_3" << endl; } 10 public: 11 int x = 666; 12 int y = 999; 13 }; 14 15 class Mother 16 { 17 public: 18 virtual void handle_1() { cout << "Mother::handle_1" << endl; } 19 virtual void handle_2() { cout << "Mother::handle_2" << endl; } 20 virtual void handle_3() { cout << "Mother::handle_3" << endl; } 21 public: 22 int a = 555; 23 int b = 888; 24 }; 25 26 class Son : public Father, public Mother //继承了两个父类 27 { 28 public: 29 void func_1() { cout << "Son::func_1" << endl; } //重写了 Father 虚函数 30 virtual void func_4() { cout << "Son::func_4" << endl; } //子类对象新写的虚函数 func_4 31 void handle_1() { cout << "Son::handle_1" << endl; } //重写了 Mother 虚函数 32 }; 33 34 typedef void(*func_t)(void); 35 36 int main(void) 37 { 38 Son son; 39 int* vptr_s_1 = (int*)*(int*)&son; //son的第一个虚表指针 40 41 for (int i = 0; i < 4; i++) 42 { 43 cout << "调用第" << i + 1 << "个虚函数:"; 44 ((func_t) * (vptr_s_1 + i))(); 45 } 46 47 for (int i = 0; i < 2; i++) 48 { 49 cout << "继承自 Father 数据成员:" << *(int*)((int)&son + 4 + i * 4) << endl; 50 } 51 52 int* vptr_s_2 = (int*)*((int*)&son + 3); //son的第二个虚表指针 53 for (int i = 0; i < 3; i++) 54 { 55 cout << "调用第" << i + 1 << "个虚函数:"; 56 ((func_t) * (vptr_s_2 + i))(); 57 } 58 59 for (int i = 0; i < 2; i++) 60 { 61 cout << "继承自 Mather 数据成员:" << *(int*)((int)&son + 16 + i * 4) << endl; 62 } 63 }
打印结果:
使用VS编译器来打印内存布局,方法如下:
项目的命令行配置中添加: /d1 reportSingleClassLayoutSon
项目属性 -> 配置属性 -> C/C++ -> 命令行
编译代码后的输出打印:
由此也可得知,多重继承的虚函数表结构如下图:
===========================================================================================================================