虚函数表的打印
来源:互联网 发布:c 动漫网站源码 编辑:程序博客网 时间:2024/06/05 09:26
虚函数表的打印
在进行打印虚函数表之前,有几个需要了解和掌握的知识点:
一. typedef 的使用
在现实生活中,信息的概念可能是长度、数量和面积等。而在计算机语言中,数据被简化成了一些基本的数据类型,如int、float、
double等。从数据的基本类型上,我们不能看出其代表的物理属性。为了使基本的数据类型具有其可知的物理属性,C语言中引入了
类型重定义语句typedef,可以为基本数据类型定义新的类型名称,从而反映数据的物理属性。
用法:typedef 基本类型名称 类型标识符
例: typedef int area; // 重定义aera为int的类型标识符。
int a;
area b; // 在类型重定义后,类型标识符可以像基本数据类型那样定义变量。
类型重定义语句 typedef 的基本用法
(1)为基本数据类型定义新的类型标识符。
typedef int Length;int a;Length b;
(2)为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型标识符。
若用普通方法定义结构体类型:
struct student{int age;char name;char sex;};struct student obj1;
在用结构体类型定义变量时,在变量名前都要加上保留字struct,而不能直接用类型名直接定义变量。
为了简化结构体变量的定义(直接用结构体类型名定义结构体变量),我们使用重定义语句typedef进行类型定义:
typedef struct student{int age;char name;char sex;};student obj1;
(3)为数组定义简洁的类型名称。
在C++中,可以将具有一定长度的数组看成一个新的数据类型,并能用重定义语句typedef对其进行标识符的重定义。
普通定义: int a[10];
用重定义语句定义数组: typedef int array[10];
array a,b,c; // 定义三个长度为10的整型数组a、b、c。
(4)为指针定义简洁的名称。
<1> 为数据指针定义简洁的名称。
typedef char * string;
string name={“wangxiaoya”};
<2> 为函数指针定义新的名称。
typedef int (*MyFun) (int a,int b);
二. 函数指针和指针函数
指针函数:返回值为地址的函数。如 int * Fun(int a,int b);
函数指针:函数名为一个指针。
与数组进行相近的理解,数组名代表数组第一个元素的地址,即数组名代表数组的首地址。同理,对于函数指针来说,函数
名为指向函数第一条指令的常量指针。
编译器在对函数进行编译时,为每一个函数分配一个首地址,存放函数的第一条指令。一般的,我们用一个指针来存放函数的
首地址,即函数指针,所以也称函数指针势函数的别名,故可以用函数指针来调用函数的内容。
如 int (*Fun) (int a,int b);
有了上述知识的铺垫,我们进行虚函数表的打印
#include<iostream>using namespace std;#include<Windows.h>class Base {public:virtual void func1(){cout << "Base::func1" << endl;}virtual void func2(){cout << "Base::func2" << endl;}private:int a;};class Derive :public Base{public:virtual void func1(){cout << "Derive::func1" << endl;}virtual void func3(){cout << "Derive::func3" << endl;}virtual void func4(){cout << "Derive::func4" << endl;}private:int b;}; typedef void(*FUNC)(void);void PrintVTable(int* VTable){cout << " 虚表地址" << VTable << endl;for (int i = 0; VTable[i] != 0; ++i){printf(" 第%d个虚函数地址 :0X%x,->", i, VTable[i]);FUNC f = (FUNC)VTable[i];f();}cout << endl;}int main(){Derive d1;PrintVTable((int*)(*(int*)(&d1)));system("pause");return 0;}
运行结果:
首先,我们要知道虚函数表在内存中的存储形式
在C++中,多态性是通过虚函数实现的,而虚函数的实现依靠虚函数表的存在。实现多态性的基本操作是将基类的对象指针指向子类对象,
通过子类对象调用函数。虚函数表中存放着重写后的虚函数。虚函数表如同一个地图,指明了实际所应该调用的函数。
C++中有规定,编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置(为了保证正确取到虚函数的偏移量)。 这意味着我们
通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。
为了打印出这张虚函数表,我们把内存中的虚函数表看做一个整型数组,数组元素就是虚函数,为了取出虚函数的地址进行强制类型转换。
核心代码:
typedef void(*FUNC)(void); //重定义函数指针名为FUNCvoid PrintVTable(int* VTable) //把虚函数表当做一个数组传入{cout << " 虚表地址" << VTable << endl; //数组名就是函数的首地址,即虚函数表的首地址for (int i = 0; VTable[i] != 0; ++i) //虚函数表的末尾元素是0,通过循环控制打印次数{printf(" 第%d个虚函数地址 :0X%x,->", i, VTable[i]);FUNC f = (FUNC)VTable[i]; f();}cout << endl;}
- 虚函数表的打印
- 打印虚函数地址的方法
- 打印数学函数值表的程序
- php的打印函数
- 打印函数的轨迹
- C++多态篇3——虚函数表详解之多继承、虚函数表的打印
- 打印虚函数地址
- 麻烦的PB打印函数
- 简单的小九九打印函数
- logSvr的日志打印函数
- itoa函数的打印问题
- 4 php的打印函数
- 打印函数的入参
- 自己封装的打印函数
- 如何打印虚表和虚函数指针的值(only for VS)
- 创建一个函数打印出表空间的大小
- 【数据结构】广义表的默认成员函数、深度、大小、打印
- 通过调用函数来实现乘法表的打印
- MapReduce程序在Map端Join
- 关于openfire的android音/视频聊天的方案问题
- mysql数据库---存储过程小记
- Linux SPI总线和设备驱动架构之三:SPI控制器驱动
- css 炫酷鎏金字体,颜色渐变
- 虚函数表的打印
- skynet环境搭建
- markdown使用学习
- MatConvNet 相关函数解释说明,MatConvNet 细节理解,MatConvNet 代码理解
- 文字识别文献阅读
- redis 持久化
- 反向传播算法最全解读,机器学习进阶必看!
- linux下 C语言 大小端测试
- Android安全之DM-verity中的Device Mapper机制分析