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. Python_爬虫_案例汇总:

    1.豆瓣采集 1 #coding:utf-8 2 #采集豆瓣书信息和图片,写进数据库 3 4 from urllib import request 5 # from bs4 import Beauti ...

  2. HDU100题简要题解(2010~2019)

    HDU2010 水仙花数 题目链接 Problem Description 春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的: "水仙花数"是指一个 ...

  3. 深度分析:面试腾讯,阿里面试官都喜欢问的String源码,看完你学会了吗?

    前言 最近花了两天时间,整理了一下String的源码.这个整理并不全面但是也涵盖了大部分Spring源码中的方法.后续如果有时间还会将剩余的未整理的方法更新到这篇文章中.方便以后的复习和面试使用.如果 ...

  4. 使用Camtasia制作我的观影报告

    最近抖音兴起做<我的观影报告>风潮.<我的观影报告>是通过剪辑影片+旁白的方法,将自己观看过的影片安利给观众的方式.如果大家想要制作这类型的观影报告,建议使用Camtasia( ...

  5. 解决Tuxera NTFS for Mac软件安装问题

    在听到小凡的电话说"Tuxera NTFS for Mac软件安装失败,怎么办"的时候,小编心里真像有一万头草泥马在奔腾--苹果软件还能安装失败!? 挥手把一万头草泥马赶走,脑补着 ...

  6. day007|python基础回顾7

    文件处理 目录 文件处理 1 文件打开模式补充 2.1 文件操作之读操作 2.2 文件操作之写操作 3 控制文件指针移动 3.1 前提 3.2 f.seek() 4 文件修改的两种方式 4.1 方式一 ...

  7. canvas 元素覆盖&穿透问题

    给网站添加canvas动态背景.完后发现有a标签无法点击,想到是canvas覆盖了(但有些是可以的).网上查找,有解决穿透的问题,但canvas的鼠标事件会无效.后发现是定位问题. canvas样式 ...

  8. echarts柱状图接口提供的数据是数值,要在顶部展示百分比

    查阅echarts配置文档,柱状图并没有类似于饼图的直接展示百分比的参数,所以需要自己配置. window.onload = function () { var list1=[25.02,19.76, ...

  9. SpringSecurity之整合JWT

    SpringSecurity之整合JWT 目录 SpringSecurity之整合JWT 1. 写在前面的话 2. JWT依赖以及工具类的编写 3. JWT过滤器 4. 登录成功结果处理器 5. Sp ...

  10. Codeforces Round #677 (Div. 3) E、G题解

    E. Two Round Dances #圆排列 题目链接 题意 \(n\)(保证偶数)个人,要表演一个节目,这个节目包含两种圆形舞蹈,而每种圆形舞蹈恰好需要\(n/2\)个人,每个人只能跳一种圆形舞 ...