虚函数的识别1

本文深入探讨了C++中虚函数的实现机制,详细解释了虚表的概念及其作用,并通过具体的代码示例展示了虚函数如何在类实例化过程中被初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.有虚函数的类在编译中会加入一个隐藏数据成员,虚表指针。这就使得类的大小比数据成员的大小大4。
2.使用默认构造函数时,构造函数中会出现虚表指针,特征是二次跳转后到跳转表,虚函数表。

    CVirtual MyVirtual;
004076D5 8D 4D E8             lea         ecx,[MyVirtual]  
004076D8 E8 A5 C6 FF FF       call        CVirtual::CVirtual (0403D82h)  ;调用默认构造函数
;虚表
_memmove:
00403D78 E9 C3 BF 08 00       jmp         memmove (048FD40h)  
charNode::length:
00403D7D E9 7E 5D 01 00       jmp         charNode::length (0419B00h)  
CVirtual::CVirtual:
00403D82 E9 49 38 00 00       jmp         CVirtual::CVirtual (04075D0h)  ;跳转
__get_thread_local_invalid_parameter_handler:
00403D87 E9 74 A1 05 00       jmp         _get_thread_local_invalid_parameter_handler (045DF00h) 
;默认构造函数
CVirtual::CVirtual:
004075D0 55                   push        ebp  
004075D1 8B EC                mov         ebp,esp  
004075D3 81 EC CC 00 00 00    sub         esp,0CCh  
004075D9 53                   push        ebx  
004075DA 56                   push        esi  
004075DB 57                   push        edi  
004075DC 51                   push        ecx  
004075DD 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
004075E3 B9 33 00 00 00       mov         ecx,33h  
004075E8 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
004075ED F3 AB                rep stos    dword ptr es:[edi]  
004075EF 59                   pop         ecx  
004075F0 89 4D F8             mov         dword ptr [this],ecx  
004075F3 8B 45 F8             mov         eax,dword ptr [this]  
004075F6 C7 00 54 8E 49 00    mov         dword ptr [eax],offset CVirtual::`vftable' (0498E54h)
; 虚表指针 
004075FC 8B 45 F8             mov         eax,dword ptr [this]  
004075FF 5F                   pop         edi  
00407600 5E                   pop         esi  
00407601 5B                   pop         ebx  
00407602 8B E5                mov         esp,ebp  
00407604 5D                   pop         ebp  
00407605 C3                   ret  
;虚表中位置 004034BD 00402CA2 一次跳转
00498E53 ??                   ?? ?? 
00498E54 BD 34 40 00 A2       mov         ebp,0A2004034h  
00498E59 2C 40                sub         al,40h  
00498E5B 00 00   
004034BD 二次跳转
@_guard_check_icall_nop@4:
004034B8 E9 93 71 00 00       jmp         _guard_check_icall_nop (040A650h)  
CVirtual::GetNumber:
004034BD E9 5E 41 00 00       jmp         CVirtual::GetNumber (0407620h)  
___acrt_show_wide_message_box:
004034C2 E9 29 D2 05 00       jmp         __acrt_show_wide_message_box (04606F0h)  
00402CA2 二次跳转
__expand_base:
00402C9D E9 DE 61 07 00       jmp         _expand_base (0478E80h)  
CVirtual::SetNumber:
00402CA2 E9 B9 49 00 00       jmp         CVirtual::SetNumber (0407660h)  

3.虚函数的识别:
类中隐式定义了一个数据成员
该数据成员在首地址处,占4字节
构造函数会将此数据成员初始化为某个数组的首地址
这个地址属于数据区,是相对固定的地址
在这个数据内,每个元素都是函数指针
他们被调用时,第一个参数必然是this指针
在这些函数内部,很有可能会对this指针使用相对间接的使用方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值