本文共 1096 字,大约阅读时间需要 3 分钟。
通过一个指针访问一个虚函数的时候,底层的调用过程,通过下面的一个简单的测试代码,看一下他的汇编指令。
class A{ public: virtual void Show1() { cout << "A1" << endl; } virtual void Show2() { cout << "A2" << endl; }};class B : public A{ public: void Show1() { cout << "B1" << endl; } void Show2() { cout << "B2" << endl; }};int main(){ A *pb = new B; pb->Show1(); pb->Show2(); return 0;}
打断点,直接反汇编
pb->Show1();//取出pb指向的对象的地址,放在eax中00AC2997 mov eax,dword ptr [pb] //eax中存储的是对象的地址,这里取出对象的前四个字节,虚函数表的地址放在edx中00AC299A mov edx,dword ptr [eax] 00AC299C mov esi,esp //取出pb指向的对象的地址,放在eax中00AC299E mov ecx,dword ptr [pb] //edx是虚函数表的地址,这里取出虚函数表的前四个字节,即第一个虚函数(Show1)的地址,放在eax中00AC29A1 mov eax,dword ptr [edx] 00AC29A3 call eax //调用eax中存放的函数 pb->Show2();00AC29AC mov eax,dword ptr [pb] 00AC29AF mov edx,dword ptr [eax] 00AC29B1 mov esi,esp 00AC29B3 mov ecx,dword ptr [pb] //上面的过程与调用Show1()一样,但是这里取出edx+4的地址,即第二个虚函数大的地址,00AC29B6 mov eax,dword ptr [edx+4] 00AC29B9 call eax
所以虚函数中没有存放函数名字,而是存放函数的地址,通过偏移来计算虚函数在虚函数表中的位置
转载地址:http://wonwi.baihongyu.com/