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; ...
随机推荐
- [LeetCode题解]19. 删除链表的倒数第N个节点 | 双指针 + 一次遍历
解题思路 双指针:第一个指针先走 n 步,然后两个指针同时走. 这里要注意当链表长度<=n,要删除头节点. 代码 /** * Definition for singly-linked list. ...
- 3、Spring Boot日志
1.日志框架 市面上的日志框架:JUL.JCL.Jboss-logging.logback.log4j.log4j2.slf4j.... 日志门面 (日志的抽象层) 日志实现 JCL(Jakarta ...
- JavaScript正则学习笔记
RegExp 元字符 ' . ' 点号:匹配任意的字符 ^ $ 位置字符 ^ 匹配字符串开始的位置 $ 匹配字符串结束的位置 匹配数字和非数字 \d 和 \D 匹配空白字符 \s 和 \S \s 匹配 ...
- python-网络安全编程第八天(实战高精度密码字典生成器)
前言 emmmm 高精度密码字典源码 1.py import exrex import sys #url过滤处理 def host_para(host): if '://' in host: host ...
- [web安全原理]PHP命令执行漏洞基础
前言 PHP命令执行漏洞 应用程序的某些功能功能需要调用可以执行系统命令的函数,如果这些函数或者函数的参数被用户控制,就有可能通过命令连接符将恶意命令拼接到正常的函数中,从而随意执行系统命令,这就是命 ...
- ctf-工具-binwalk
binwalk在玩杂项时是个不可缺的工具.1.最简单的,在玩隐写时,首先可以用它来找到其中的字符串例如:在铁人三项,东北赛区个人赛中,有一道题它直接给了一个文件,没有后缀,不知道是什么文件先binwa ...
- 新鲜出炉!面试90%会被问到的Java多线程面试题,史上最全系列!
前言 最近很多粉丝朋友私聊我说能不能给整理出一份多线程面试题出来,说自己在最近的面试中老是被问到这一块的问题被问的很烦躁,前一段时间比较忙没时间回私信,前两天看到私信我也是赶紧花了两天给大家整理出这一 ...
- CA证书与https讲解
最近面试问到这个问题,之前了解过但答的不是很好,再补充补充一下https方面的知识. 备注:以下非原创文章. CA证书与https讲解 1.什么是CA证书. ◇ 普通的介绍信 想必大伙儿都听说过介绍信 ...
- 下载器Folx怎么安装使用
应该使用哪个下载工具?这个如果是Windows上会有无数答案的问题,在Mac上却变得异常的纠结.比如Leech和Aria2,这两款软件,前者功能相对比较简单,后者的配置又稍微有点复杂,很难找到一款相对 ...
- Math对象-JavaScript
Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法.Math 不是一个函数对象. Math 用于 Number 类型. Math 的所有属性与方法都是静态的. 属性 Math.E 欧拉常数 ...