1625-5 王子昂 总结《2017年5月21日》 【连续第232天总结】
A. 加密与解密 虚函数
B. C++的面向对象模型的最核心概念是虚函数。
虚函数是在程序运行时定义的函数,虚函数的地址是不能再编译时 确定的,只能在调用即将进行时确定
对所有虚函数的引用通常都放在一个专用数组,虚函数表,中,每个至少使用一个虚函数的对象里面都具有的虚函数表指针
虚函数通常通过指向虚函数表的指针间接加以引用
eg源代码:
class CSum
{
public:
virtual int Add(int a, int b)
{
return (a + b);
}
virtual int Sub(int a, int b)
{
return (a - b);
}
};
void main()
{
CSum* pCSum = new CSum ;
pCSum->Add(1,2);
pCSum->Sub(1,2);
}
用VC++编译后的汇编代码为:
push esi
push 4
call 00401060 ;new(), 位新建对象实例分配4字节
add esp,4
test eax,eax
je short 00401019
mov dword ptr [eax], 4050A0 ;将4050A0h写入创建的对象实例之中。4050A0h是CSum类虚函数表的指针(VRBL),表中的元素是CSum类的虚函数,它们指向CSum函数的成员
mov esi,eax ;ESI=VTBL
jmp short 0040101B
xor esi,esi ;用NULL指向对象实例指针,该分支在内存分配失败才会来到,空指针将激活SEH
mov eax,dword ptr [esi] ;eax=*BTBL=**Add()
push 2
push 1
mov ecx,esi ;BCX=this
call dword ptr [eax] ;对虚汗的调用,此时EAX=*VTBL=**Add(),即call 401040
mov edx,dword ptr [esi]
push 2
push 1
mov ecx,esi ;ECX=this
call dword ptr [edx+4] ;call [VTBL+4]
pop esi
retn
这段代码首先调用new函数分配类所需的内存,调用成功后eax保存分配内存的指针,然后将对象实例指向CSum类虚函数表(VTBL)4050A0h。
而此时在VTBL中有两组数据:
[VTBL]=401040h ;Add()
[VTBL+4]=401050h;Sub()
也就是说,虚函数的使用仍然是利用this指针找到对象地址,然后再根据VTBL找到所调用的虚函数的地址的
C. 明日计划
加密与解密 控制语句