探究c++虚表实现代码
本文简单探究虚表实现。
如下代码中有一个基类CPerson
和子类CStudent:public
.并有两个虚函数run
和cry
。
#includeusing namespace std; class CPerson {public: virtual void run() {cout << "Person isruning. \r\n"; } virtual void cry() {cout << "Person iscry. \r\n"; }}; class CStudent:public CPerson {public: void run() {cout << "Student isruning. \r\n"; } void cry() {cout << "Student iscry. \r\n"; }}; int main() { CPerson * pStudent = new CStudent(); pStudent->run(); getchar(); return 0; }
VS
中cl
提供了对应命令行查看类的内存布局。语法
cl /d1 reportSingleClassLayoutXXXX YYYY
。其中XXX为类名,YYYY
为所在文件全路径。如本例:
cl /d1 reportSingleClassLayoutCStudent \\Mac\Main.cpp
输出如下:文章图片
我们再看下
CPerson
的输出:文章图片
上面的图可能很抽象,大致的意思一个
CStudent
的内存区域中的第一个内存区域存放一个4字节指针
,指针指向一个另一个内存区域,这个内存区域我们称为虚表。虚表内存结构可以理解为一个数组,数组中的每个元素是一个函数指针。指向函数地址。示例图:
【探究c++虚表实现代码】
文章图片
空说无凭,我们利用VS内存查看器和汇编器证实猜测。
文章图片
上图简单来说就是:
(1) 构造了一个CStudent对象,地址为
0x00d88d28
(2) 进入对象的地址,对象内存的第一个4字节区域为
0x00f89b78
,这个存储的数值为虚表指针位置。(3) 进入虚表内存地址,发现存储了两个指针
0xf8105f
,0xf81406
.我们再次跳转到
0xf8105f
内存地址,此时我们查看汇编级别代码。发现是一个jmp指令跳转到实际CStudent::run函数.文章图片
同理
0xf81406
如下图所示:文章图片
其他扩展知识:
虚表在编译时已经构造完成,在构造对象时,会根据对象的类型在初始化时赋值虚表地址给对象的
vfptr
。我们把这种行为称为动态绑定(Dynamic Binding)到此这篇关于探究c++虚表实现代码的文章就介绍到这了,更多相关c++虚表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- c++基础概念笔记
- unity探究UGUI的Image中sprite和overrideSprite的区别
- 牛逼!C++开发的穿越丛林真人游戏,游戏未上线就有百万人气
- C++Primer之|C++Primer之 函数探幽
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- QML基础信息
- C++-类型转换
- MongoDB|MongoDB - 简介