C++ 虚函数表与多态 —— 继承的虚函数表 & 内存布局
1. 使用继承的虚函数表:
如果不涉及多重继承,每个类只有1个虚函数表,当子类继承父类后,子类可以自己改写和新增虚函数,如下图所示:

子类重写 func_1 后,子函数的 func_1 将会有新的逻辑,不会干扰到父类;
子类新增行的 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"; }
8 virtual void func_2() { cout << "Father::func_2"; }
9 virtual void func_3() { cout << "Father::func_3"; }
10 public:
11 int x = 666;
12 int y = 999;
13 };
14
15 class Son : public Father
16 {
17 public:
18 void func_1() { cout << "Son::func_1 "; } //重写了虚函数
19 virtual void func_4() { cout << "Son::func_4 "; } //子类对象新写的虚函数 func_4
20 };
21
22 typedef void(*func_t)(void);
23
24 int main(void)
25 {
26 Father father;
27 cout << "father 对象地址:" << (int*)&father << endl;
28 int* vptr_f = (int*)*(int*)&father; //虚表指针
29
30 for (int i = 0; i < 3; i++) //这里如果想循环4次往下访问,不会访问到子类的 func_4 ,会访问到非法内存
31 {
32 cout << "调用第" << i + 1 << "个虚函数:";
33 ((func_t) * (vptr_f + i))();
34 cout << "地址为:" << *(int*)(vptr_f + i) << endl;
35 }
36
37 cout << "==============================================" << endl;
38
39 Son son;
40 cout << "son 对象地址:" << (int*)&son << endl;
41 int* vptr_s = (int*)*(int*)&son; //虚表指针
42
43 for (int i = 0; i < 4; i++)
44 {
45 cout << "调用第" << i + 1 << "个虚函数:";
46 ((func_t) * (vptr_s + i))();
47 cout << "地址为:" << *(int*)(vptr_s + i) << endl; //打印每个虚函数的地址
48 }
49
50 for (int i = 0; i < 2; i++)
51 {
52 cout << *(int*)((int)&son + 4 + i * 4) << endl;
53 }
54 cout << "sizof(son)==" << sizeof(son) << endl;
55 }
运行结果:

子类的虚函数表生成:
看上图可知,子类对象的 func_1() 地址与父类的 func_1() 地址便可知,重写的虚函数并不是把父类的同名函数覆盖改写,而是在新内存新写。
子类对象是先将父类虚函数表的成员地址全部复制下来,如果子类重写了父类的某个虚函数,便将被重写虚函数的指针,改为新虚函数的指针(指针替换)。
如果子类增加了新的虚函数,那么就会把这个虚函数的地址添加到虚函数表的表尾部。
注意:如果仔细观察我们可以发现,上图中按顺序走的虚函数所存放的地址不同,Father的3个func函数地址不是线性排序。
===========================================================================================================
C++ 虚函数表与多态 —— 继承的虚函数表 & 内存布局的更多相关文章
- C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)
今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化 译 译者前言 一个C ...
- C++ 虚函数表与多态 —— 多重继承的虚函数表 & 内存布局
多重继承的虚函数表会有两个虚表指针,分别指向两个虚函数表,如下代码中的 vptr_s_1.vptr_s_2,Son类继承自 Father 和 Mather 类,并且改写了 Father::func_1 ...
- Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)
原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...
- C++对象的内存布局以及虚函数表和虚基表
C++对象的内存布局以及虚函数表和虚基表 本文为整理文章, 参考: http://blog.csdn.net/haoel/article/details/3081328 http://blog.csd ...
- 【整理】C++虚函数及其继承、虚继承类大小
参考文章: http://blog.chinaunix.net/uid-25132162-id-1564955.html http://blog.csdn.net/haoel/article/deta ...
- 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。
本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...
- c++继承中的内存布局
今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化 译 译者前言 一个C ...
- C++各种类继承关系的内存布局
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- C++ 各种继承方式的类内存布局
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
随机推荐
- IP地址分类的计算方法
IP地址由四段组成,每个字段是一个字节,8位,最大值是255,但实际中我们用点分十进制记法. IP地址由两部分组成,即网络地址和主机地址.网络地址表示其属于互联网的哪一个网络(常见ABC三类,以固定网 ...
- Linux Shell操作 执行C代码显示当前路径
在unix系统下一切皆文件,文件夹是文件的一种.设备也会对应到相应的文件类型. 基础知识: . 代表当前路径 ..代表上级目录(父目录) / 在路径的最前边的时候代表树根.在路径中间的时候只不过是路径 ...
- 《Machine Learning in Action》—— 懂的都懂,不懂的也能懂。非线性支持向量机
说在前面:前几天,公众号不是给大家推送了第二篇关于决策树的文章嘛.阅读过的读者应该会发现,在最后排版已经有点乱套了.真的很抱歉,也不知道咋回事,到了后期Markdown格式文件的内容就解析出现问题了, ...
- 一遍记住Java常用的八种排序算法
1.直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中. 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列. 对第四个数.第五个数--直 ...
- Python一行式代码
# 简易Web Server,可以直接快速共享文件 python -m http.server # 脚本性能分析 python -m cProfile my_script.py # 列表辗平 impo ...
- Java Web 会话技术总结
会话技术 会话概念 一次会话中包含多次请求和响应. 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止,一次会话结束. 会话的功能 在一次会话的范围内的多次请求间,共享数据. 会 ...
- zabbix、Cacti、Nagios、open-falcon、Ganglia、Prometheus开源监控比较
Zabbix 一个基与WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案(普遍) 能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存在的 ...
- FL Studio杂项设置页讲解(下)
上篇文章中我们重点讲解了FL Studio中"截断/被截"如何有效的避免个采样在播放时相互干扰的知识以及电平设置栏的知识,今天我们将讲完该页面中剩下的栏目知识,一起来看看吧! 1. ...
- 简单实用的Boom 3D进阶使用教程分享
对于初学者来说,简单体验Boom 3D的3D环绕音效,就可以通过普通耳机享受到高品质耳机的动人音效.而对于进阶者来说,Boom 3D灵活的预设功能,能让其享受到自由调整均衡器.低音的乐趣. 图1:Bo ...
- 安装git和lsof
yum install git yum install lsof 查看80端口 lsof -i:80