凌云窟
南山巅上火麟烈,北海潜深雪饮寒。可怜两锋未缘见,雪刀封隐孤剑鸣。
<2007年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

留言簿(0)

随笔分类

随笔档案

文章档案

相册

简历下载

搜索

最新评论

阅读排行榜

评论排行榜

 
VC知识库BLOG   首页  新随笔  联系  聚合  登录 
  随笔-22 文章-0 评论-38 Trackbacks-0
2007年6月27日

  好久不写blog都生疏了,刚好公司要组织一次C++的基本功考试,就一个派生类调用虚函数的问题研究了一下编译器的实现:

class A
{
public:
    A()
{}
    
~A(){}
     
virtual void Display(){cout<<"A"<<endl;}
}
;

class B:public A
{
public:
    B()
{Display();}
    
~B(){}
    
virtual void Display(){cout<<"B"<<endl;}
}
;
int main()
{
   B 
*pBb = new B;
   delete pBb;
}
在B(){Display();}设定一个断点,跟踪到汇编代码得到如下代码:
00401391   mov         eax,dword ptr [ebp-10h]
00401394   mov         dword ptr [eax],offset B::`vftable' (00432020)
0040139A   mov         ecx,dword ptr [ebp-10h]
0040139D   call        @ILT+155(B::Display) (004010a0)
前三排的代码是设置虚函数表,然后直接调用了B::Display函数,并没有通过虚函数表间接调用这个函数。这说明在构造函数中虽然虚函数表已经设置好了,但是调用虚函数是不会使用虚函数表的,是直接调用.

下面的代码是非构造函数内经过虚函数表间接调用Display的汇编码:
0040127E   mov         edx,dword ptr [ebp-10h]
00401281   mov         eax,dword ptr [edx]
00401283   mov         esi,esp
00401285   mov         ecx,dword ptr [ebp-10h]
00401288   call        dword ptr [eax]
发表于 2007-06-27 22:33 莫问春秋 阅读(4860) | 评论 (5)编辑 收藏