C++浅析——虚函数的动态和静态绑定
源自一道面试题,觉得很有意思
class CBase
{
public:
virtual void PrintData(int nData = 111);
};
void CBase::PrintData(int nData /* = 111 */)
{
printf("CBase::PrintData, nData = %d\n", nData);
} class CDerived : public CBase
{
public:
void PrintData(int nData = 222);
};
void CDerived::PrintData(int nData /* = 111 */)
{
printf("CDerived::PrintData, nData = %d\n", nData);
}
在main()中做如下调用:
CDerived oCDerived;
CBase* pCBase = (CBase*)&oCDerived; pCBase->PrintData();
(*pCBase).PrintData();
oCDerived.PrintData();
大家先猜猜输出结果是什么?
是不是更奇怪,我们看看反汇编的代码:
14、oCDerived.PrintData();
push 0DEh
lea ecx,[ebp-4]
call @ILT+25(CDerived::PrintData) (0040101e) ;直接调用CDerived::PrintData(),无虚表取址过程 15、((CBase)oCDerived).PrintData();
mov esi,esp
push 6Fh ;压入CBase::PrintData()形参
lea ecx,[ebp-4]
push ecx ;压入oCDerived的this指针
lea ecx,[ebp-10h]
call @ILT+10(CBase::CBase) (0040100f) ;调用CBase拷贝构造函数新创建了一个CBase对象
mov dword ptr [ebp-14h],eax
mov edx,dword ptr [ebp-14h]
mov eax,dword ptr [edx] ;取新CBase对象的虚表
mov ecx,dword ptr [ebp-14h]
call dword ptr [eax] ;调用新CBase对象的虚表的第一个函数 15.1、CBase::CBase拷贝构造函数;
mov dword ptr [ebp-4],ecx ;取this指针
mov eax,dword ptr [ebp-4]
mov dword ptr [eax],offset CBase::`vftable' (00425024) ;虚表地址赋值,直接用的CBase虚表,而没有用CDerived的虚表
mov eax,dword ptr [ebp-4] ;将this指针给eax返回 16、pCDerived->PrintData();
mov esi,esp
push 0DEh
mov ecx,dword ptr [ebp-8] ;取pCDerived
mov edx,dword ptr [ecx] ;取虚表
mov ecx,dword ptr [ebp-8] ;放入this指针
call dword ptr [edx] ;调用虚表的第一个函数,即PrintData()
C++浅析——虚函数的动态和静态绑定的更多相关文章
- C++中虚函数实现原理揭秘
编译器到底做了什么实现的虚函数的晚绑定呢?我们来探个究竟. 编译器对每个包含虚函数的类创建一个表(称为V TA B L E).在V TA B L E中,编译器放置特定类的虚函 ...
- C++虚函数【Java有虚函数吗?】
1,简单介绍 定义在基类中的函数,子类必须对其进行覆写![必须对其进行覆写?!]——Java中的接口.Abstract方法中的抽象类也有这样的要求. C++中定义: virtual void deal ...
- [转载]C++虚函数浅析
原文:http://glgjing.github.io/blog/2015/01/03/c-plus-plus-xu-han-shu-qian-xi/ 感谢:单刀土豆 C++虚函数浅析 JAN 3RD ...
- C++中的重载,隐藏,覆盖,虚函数,多态浅析
直到今日,才发现自己对重载的认识长时间以来都是错误的.幸亏现在得以纠正,真的是恐怖万分,雷人至极.一直以来,我认为重载可以发生在基类和派生类之间,例如: class A { public: void ...
- C++中虚函数的作用浅析
虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...
- MFC浅析(7) CWnd类虚函数的调用时机、缺省实现
CWnd类虚函数的调用时机.缺省实现 FMD(http://www.fmdstudio.net) 1. Create 2. PreCreateWindow 3. PreSubclassWindow 4 ...
- C++ 虚函数与纯虚函数 浅析
[摘要] 在虚函数与纯虚函数的学习中.要求理解虚函数与纯虚函数的定义,了解虚函数与纯虚函数在实例化上的差异.掌握两者在实现上的必要性.熟悉纯虚函数在子类与孙类的函数类型.本文即针对上述问题展开阐述. ...
- C++:抽象基类和纯虚函数的理解
转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...
- 【C++】多态性(函数重载与虚函数)
多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...
随机推荐
- java内存模型-final
与前面介绍的锁和 volatile 相比较,对 final 域的读和写更像是普通的变量访问.对于final 域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个 final 域的写入,与随后把 ...
- ajax的再次封装!(改进版) —— new与不 new 有啥区别?
生命不息重构不止! 上一篇写了一下我对ajax的再次封装的方法,收到了很多有价值的回复,比如有童鞋建议用$.extend,一开始还以为要做成插件呢,后来才知道,原来这个东东还可以实现合并.省着自己再去 ...
- 20个最新的照片 PS 技巧,提升摄影水平
相信很多人都知道 Photoshop 在照片编辑方面的强大,所以几乎每张照片经过 PS 处理后都可以变成一个真正的杰作.这里分享的这组 Photoshop 教程可以帮助你学习到新的照片处理技术.你会发 ...
- [js开源组件开发]loading加载效果
loading加载效果 由于程序和网络的原因,常常我们需要在交互的时候,给用户一个正在加载中的动画,于是,loading组件横空出世.不需要复杂的代码,也能完成大多数业务,这就是我做组件的原则. 效果 ...
- 优秀的CSS框架---bootstrap
Bootstrap是Twitter推出的一个用于前端开发的开源工具包.它 由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架.现在在网上已经有 ...
- Jquery在线引用地址
Jquery在线引用地址: 1. 很多网站都是使用这种方式引入,客户的浏览器可能已经缓存过了 jquery.可以直接调用本地的,速度更快… 2. Google code 使用了 cdn 技术在很多地方 ...
- SAP中删除假脱机请求
好几次公司的SAP都碰到所有的SMARTFORM都打印不了的情况.查了一下原因原来是假脱机请求太多了.清了一下,问题就解决了. 删除假脱机请求的一些方法: 1.避免经常出现此类错误,最好还 ...
- 如何实现SP文档库类似百度文档库的效果 (副标题:如何在SP2013文档库的SWF文件用FlexPager显示)
1. 编辑文档库列表显示页面,如下图: 2. 添加内容编辑器,如下图: 3. 添加如下在[内容编辑器中]-[编辑源],添加如下JS代码,如下图: 代码如下: <scrip type=&quo ...
- BT5 & Kali Linux 网卡选择
[需要注意的几点]: 芯片类型 知否支持外接天线 网卡固件版本 支持的无线协议 网卡功率 BT5/Kali RC3支持网卡: RTL8187, R8187 (Realtek) 功率高.兼容性好 Ra ...
- Java学习心得之 Linux下搭建JavaWeb环境
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Java学习心得之 Linux下搭建JavaWeb环境 1. 前言2. Java安装3. t ...