反汇编:虚函数表

多态中virtual的工作原理

正常实现多态的代码

#include "stdafx.h"
class Base{
public:
virtual HowVirtual(){
printf("the Base virtual");
}
};
class Son:public Base{
public:
virtual HowVirtual(){
printf("the Son virtual");
}
};
void theVir(Base& fath){
fath.HowVirtual();
}
int main(int argc, char* argv[])
{
Base b;
Son s;
//theVir(s);
//theVir(b);
printf("\n");
return 0;
}

问题:为什么可以实现多态的功能?也就是相同方法下,编译器是如何判断传入的是哪个对象所以调用该对象实现的方法的?

如下地方进行断点,然后进行运行,可以发现每个对象中都会存在一个__vfptr名称的一个指针,该指针指向一个地址为0x00422f9c0x0042210c,展开选项为如下:

这里面最终的地址分别是指向的是004010190040102d,然后跟过去00401019发现是个跳转,如下:

00401019 jmp Base::HowVirtual (0040d8c0)

那么跟0040d8c0可以发现是Base::HowVirtal方法

而子类的虚拟表中同样进行操作,发现结果是如下:

0040102D jmp Son::HowVirtual (0040d950)

那么大家就可以理解了,使用virtual的时候能够实现多态的功能!

还需要注意的是

1、实现了虚函数则会在当前对象中占四个字节,因为它是一个指向虚函数表的一个指针

2、当虚函数越多的时候,__vfptr地址中保存的值只是存储所有虚函数的首地址(也就是该地址只是保存了真正虚拟表的地址),比如现在定义了两个虚函数,如下:

继续跟发现如下:虚函数是连续的!

posted @   zpchcbd  阅读(498)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示