多重继承的虚函数表会有两个虚表指针,分别指向两个虚函数表,如下代码中的 vptr_s_1vptr_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++ -> 命令行

编译代码后的输出打印:

由此也可得知,多重继承的虚函数表结构如下图:

===========================================================================================================================

C++ 虚函数表与多态 —— 多重继承的虚函数表 & 内存布局的更多相关文章

  1. 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。

    本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...

  2. C++ 虚函数表与多态 —— 继承的虚函数表 & 内存布局

    1. 使用继承的虚函数表: 如果不涉及多重继承,每个类只有1个虚函数表,当子类继承父类后,子类可以自己改写和新增虚函数,如下图所示: 子类重写 func_1 后,子函数的 func_1 将会有新的逻辑 ...

  3. 浅析GCC下C++多重继承 & 虚拟继承的对象内存布局

    继承是C++作为OOD程序设计语言的三大特征(封装,继承,多态)之一,单一非多态继承是比较好理解的,本文主要讲解GCC环境下的多重继承和虚拟继承的对象内存布局. 一.多重继承 先看几个类的定义: 01 ...

  4. C++对象模型 多重继承与虚函数表

    一 多重继承 1) 代码: Code#include <iostream>using namespace std; class B1{public:    int x;    virtua ...

  5. [C++对象模型][8]多重继承与虚函数表

    转载: [C++对象模型][8]多重继承与虚函数表 一 多重继承 1) 代码: Code #include <iostream> using namespace std; class B1 ...

  6. C++ 虚函数表与多态 —— 虚函数表的内存布局

       C++面试经常会被问的问题就是多态原理.如果对C++面向对象本质理解不是特别好,问到这里就会崩. 下面从基本到原理,详细说说多态的实现:虚函数 & 虚函数表.   1. 多态的本质: 形 ...

  7. 虚函数表-C++多态的实现原理

    目录 1.说明 2.虚函数表 3.代码示例 参考:http://c.biancheng.net/view/267.html 1.说明 我们都知道多态指的是父类的指针在运行中指向子类,那么它的实现原理是 ...

  8. C++对象的内存布局以及虚函数表和虚基表

    C++对象的内存布局以及虚函数表和虚基表 本文为整理文章, 参考: http://blog.csdn.net/haoel/article/details/3081328 http://blog.csd ...

  9. vs查看虚函数表和类内存布局

    虚继承和虚基类 虚继承:在继承定义中包含了virtual关键字的继承关系:     虚基类:在虚继承体系中的通过virtual继承而来的基类,需要注意的是:class CSubClass : publ ...

随机推荐

  1. 西数WD2T硬盘分区对齐的方法

    新购一个西数2T硬盘,也就是绿盘的那种,淘宝500左右,支持高级格式化. 到手以后,分区格式化,前几天格式化完成以后,fdisk -l 发现如下文字 引用 Partition 1 does not s ...

  2. .NET 5 带来的新特性 [MemberNotNull] 与 [MemberNotNullWhen]

    MemberNotNullAttribute是 .NET 5 的新增特性,位于System.Diagnostics.CodeAnalysis.该特性用于显式声明,调用此方法后该值不再为 Null.示例 ...

  3. C#高级编程之泛型二(泛型类型约束、类型、反射与泛型)

    泛型类型约束 简言之:对泛型类型进行约束,细化,限定. MSDN的定义:泛型定义中的 where 子句指定对用作泛型类型.方法.委托或本地函数中类型参数的参数类型的约束,意思就是可以有泛型类.泛型方法 ...

  4. kali linux与虚拟机Vmware安装vmware tools(主机与虚拟机的文件拖拽)

    一.打开虚拟机任务栏"虚拟机"-----点击安装Vmware tools 二.回到开启的kali linux系统中,找到vmware tools CD文件夹,拖拽出文件中的压缩文件 ...

  5. 转化dataframe中一组序列为时间序列的方法-to_datetime()的最新用法

    一.to_datetime()的最新用法: hs300_hf['date'] = pd.to_datetime(hs300_hf['date']) hs300_hf.set_index('date', ...

  6. Guitar Pro7应该怎么添加音色

    众所周知,音色是乐器的灵魂所在.音色的好坏,直接影响到了整首曲子的质量.Guitar Pro7中,用户不仅可以切换乐器模拟器,还能分别对其进行音色调整.对于新手而言,Guitar Pro7是一款非常合 ...

  7. jQuery 第十章 ajax 什么是回调地狱 优化回调地狱

    回调地狱 什么是回调地狱,回调函数,一个嵌套着一个,到最后,缩略图成了 一个三角形, 造成了可阅读性差,可阅读性差就代表代码的可维护性 和 可迭代性差,最后还有一个就是可扩展性差. 也不符合设计模式的 ...

  8. laravel数据填充

    post表有这2个字段 填充20条数据, 执行 php artisan tinker 执行预览 factory(App\Post::class,20)->make(); 插入数据库 factor ...

  9. Linun中配置redis密码

    这里以linux服务器为例,为redis配置密码. 1.第一种方式 (当前这种linux配置redis密码的方法是一种临时的,如果redis重启之后密码就会失效,) (1)首先进入redis,如果没有 ...

  10. Codeforces Round #674 (Div. 3) C、D 题解

    C.Increase and Copy #枚举 题目链接 题意 最初你有仅包含一个数字\(1\)的数组\(a\),一次操作中可对该数组进行两类操作: 从数组中选择一个元素,将该元素\(+1\): 从数 ...