c++ 虚函数内存浅析(一)
来源:互联网 发布:windows应用商店误删 编辑:程序博客网 时间:2024/05/17 03:33
c++ 虚函数内存浅析(一)
一:引子
c++和其他面向对象的语言一样,都有多态,封装,继承的特性,多态主要靠重载和覆盖来实现。 如果用我自己的理解来对多态进行定义,那么“根据不同的上下文语境,使用不同的同名函数 需求的一种方法。”这样的说法可能更容易理解一些。虚函数是实现重载和覆盖的重要手段, 那么对于虚函数,编译器做了哪些工作;以及代码在cpu上到底是如何实现的呢?
二:正文
简单模式下的内存情景
- 构造,析构函数顺序
- 测试代码
类的继承关系如下:
- 测试代码
class BaseTestA{public: BaseTestA() { m_countA = 0xa0; printf("BaseTestA in \n"); } ~BaseTestA() { printf("BaseTestA out \n"); } void PrintFun() { printf("BaseTestA \n"); } virtual void virPrint() { printf("Base virtual print A \n"); } int m_countA;};// 单线继承class TestB : public BaseTestA{public: TestB() { m_countB = 0xb0; printf("TestB in \n"); } ~TestB() { printf("TestB out \n"); } virtual void PrintFun() { printf("TestB \n"); } virtual void virPrint() { printf("virPrint print B \n"); } virtual void virRun() { printf("virRun print B \n"); } int m_countB;};
执行测试代码:
void test(){ BaseTestA *testA = new TestB; testA->PrintFun(); testA->virPrint(); TestB testB; testB.PrintFun();}int _tmain(int argc, _TCHAR* argv[]){ test(); // 等待结果查看 char c = getchar(); return 0;}
执行顺序: 父类的构造函数->子类的构造函数; 子类的析构函数->父类的析构函数。
简单模式下的顺序比较简单,有兴趣的可以用od或者windbg详细跟踪下一个子类的建立与消亡的过程。
在构造函数的跟踪过程中会发现:
1. 每一个类都会有一个虚函数表,对每一个类的构造时,都会将+0偏移的位置用虚函数表指针写入。
2. 子类的虚函数表和父类的虚函数表中,同名的函数在各自的虚函数表中的偏移是相同的。
虚函数在调用时,是this调用方式,一般将ecx作为this指针进行寄存器传参,而且虚函数在调用寻址时都是从虚函数表中的偏移获取所得如:
mov ecx,eax
call [eax+0x68]
内存布局
简单情形下的内存布局也比较简单,在这里发图说明:成员变量和虚函数的顺序都是 父类在上,依次往下子类的。
如果父类和子类有虚函数是覆盖或者重载实现的,那么子类的虚函数会覆盖掉父类的同名虚函数。
这个是在编译器自动完成的,也就是说,如果一个exe生成了,那么每一个类的虚函数表都是固定值。
0 0
- c++ 虚函数内存浅析(一)
- C语言函数浅析
- C++inline函数浅析
- 浅析Objective-C内存管理
- 浅析C指针(一)
- class.c重要函数浅析
- 一分钟了解“c语言开辟内存函数malloc”
- 浅析Linux内存映射: mmap ( 一)
- Android 内存浅析【泄漏、溢出】【一】
- Android 内存浅析【一】【管理、机制、分析】
- android防止内存溢出浅析(一)
- linux内存管理浅析(一)
- Linux内存管理浅析(一)
- 浅析C/C++内存泄漏的解决办法
- 浅析Objective-C的内存管理机制
- 浅析C语言数据内存布局
- 浅析C\C++的动态内存管理
- C内存管理函数
- 用Qemu模拟vexpress-a9 (二) --- 创建根文件系统
- okhttp学习笔记--网络框架封装
- Android webview 快照及白屏闪屏解决方案
- HTML5创建 cache manifest缓存文件
- 树莓派3B创建WiFi热点
- c++ 虚函数内存浅析(一)
- 最长合成字符串
- 51nod-距离之和最小(中位数)
- 阻止冒泡方法
- 用WM_CONCAT查询数据的时候超过10条报不存在的lob值, 弄了一上午终于搞定了!
- 编写Strom启动和停止集群的脚本
- 使用Dlib编程出现X11相关错误
- python安装mysql
- 融云基于IMkit自定义会话列表