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++ 虚函数表与多态 —— 继承的虚函数表 & 内存布局的更多相关文章

  1. C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)

    今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化    译 译者前言 一个C ...

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

    多重继承的虚函数表会有两个虚表指针,分别指向两个虚函数表,如下代码中的 vptr_s_1.vptr_s_2,Son类继承自 Father 和 Mather 类,并且改写了 Father::func_1 ...

  3. Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)

    原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...

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

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

  5. 【整理】C++虚函数及其继承、虚继承类大小

    参考文章: http://blog.chinaunix.net/uid-25132162-id-1564955.html http://blog.csdn.net/haoel/article/deta ...

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

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

  7. c++继承中的内存布局

    今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化    译 译者前言 一个C ...

  8. C++各种类继承关系的内存布局

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  9. C++ 各种继承方式的类内存布局

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

随机推荐

  1. 「NOIP2016」天天爱跑步 题解

    (声明:图片来源于网络) 「NOIP2016」天天爱跑步 题解 题目TP门 题目 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是 ...

  2. 查看php扩展

    php -m

  3. javascript实现文件上传之前的预览功能

    1.首先要给上传文件表单控件和图片控件设置name属性 <div class="form-group">                    <label fo ...

  4. FL Studio通道窗口和步进音序器知识讲解

    FL Studio中通道窗口是以样本为概念的音乐制作基础.通道窗口包含了步进音序器并结合了各种丰富的功能,可以通过通道窗口打开各通道的设置窗口.钢琴卷轴等.步进音序器在节奏制作方便表现出很好的优势,它 ...

  5. SFTP 连接服务器下载文件方法采坑说明

    本篇博客主要记录请求SFTP服务器的一些方法采坑情况. 采坑的方法说明: 1. cd():这个方法用于进入某个目录下. 默认情况,当连接SFTP服务器成功后直接进入用户目录,比如我连接自己本机SFTP ...

  6. P3694 邦邦的大合唱站队 题解

    \( 数据范围暗示状压,爪巴. \\ 首先考虑状态量. \\ 我们设计一个关于乐队数量的状态 S, 代表排列好的乐队.\\ \) eg: if(Set_排列好的队列 = {1, 2, 5}) then ...

  7. [从源码学设计]蚂蚁金服SOFARegistry网络操作之连接管理

    [从源码学设计]蚂蚁金服SOFARegistry网络操作之连接管理 目录 [从源码学设计]蚂蚁金服SOFARegistry网络操作之连接管理 0x00 摘要 0x01 业务领域 1.1 应用场景 0x ...

  8. Mybatis【2.1】-- 从读取流到创建SqlSession发生了什么?

    目录 1.Resources.getResourceAsStream("mybatis.xml")到底做了什么? 2. new SqlSessionFactoryBuilder() ...

  9. Java集合【6.1】-- Collection接口源码详解

    目录 一.Collection接口简介 二.Collection源码分析 三.Collection的子类以及子类的实现 3.1 List extend Collection 3.2 Set exten ...

  10. vue微博回调接口

    1.vue微博回调空页面 注:微博回调空页面为: http://127.0.0.1:8888/oauth/callback/ 1.1 页面路径 components\oauth.vue <tem ...