设为首页 加入收藏

TOP

关于C++虚函数的研究(一)
2013-04-10 11:53:20 来源: 作者: 【 】 浏览:545
Tags:关于 函数 研究

  以前早稍有接触C++(www.cppentry.com)中虚函数多态在编译器上的实现问题,金山面试时还着重问了这个问题。但总没有利用程序来检查实验。这次终于对虚函数和他的vtable表有更深入的关注,通过继承类大小的检测和反汇编后的代码能查出端倪,例如测试程序如下:

  #include <conio.h>

  #include <iostream>

  using namespace std;

  class A

  {

  private:

  char is[20];

  public:

  char ss[20];

  void f1() {cout<<"This A.f1"<<endl; }

  virtual void f2()  { cout<<"This A.f2"<<endl; }

  virtual void f3()  { cout<<"This A.f3"<<endl; }

  };

  class B:public A

  {

  void f1() {cout<<"This B.f1"<<endl; }

  void f2()  { cout<<"This B.f2"<<endl; }

  //void f3()  { cout<<"This B.f3"<<endl; }

  };

  void main()

  {

  cout<<sizeof(A)<<endl;

  cout<<sizeof(B)<<endl;

  A a,*p;

  B b;

  if(getch() == 'c')

  p = &b;

  else

  p = &a;

  p->f1();

  p->f2();

  p->f3();

  }

  发现sizeof(A)=sizeof(B)=44,除了数组共40个字节外,还有4个字节多于。最终调试发现,只要父类有虚函数,而又无论函数个数是多少,父类和所有继承于他的子类都多4个字节,做什么用的呢?存放一个指针,指向vtable表,反汇编显示:

  32:       p->f1();

  00401626   mov         ecx,dword ptr [ebp-30h]

  00401629   call        @ILT+325(A::f1) (0040114a)

  33:       p->f2();

  0040162E   mov         edx,dword ptr [ebp-30h]

  00401631   mov         eax,dword ptr [edx]

  00401633   mov         esi,esp

  00401635   mov         ecx,dword ptr [ebp-30h]

  00401638   call        dword ptr [eax]

  0040163A   cmp         esi,esp

  0040163C   call        __chkesp (00420bc0)

  34:       p->f3();

  00401641   mov         ecx,dword ptr [ebp-30h]

  00401644   mov         edx,dword ptr [ecx]

  00401646   mov         esi,esp

  00401648   mov         ecx,dword ptr [ebp-30h]

  0040164B   call        dword ptr [edx+4]

  0040164E   cmp         esi,esp

  00401650   call        __chkesp (00420bc0)

  35:   }

  到00401638   call        dword ptr [eax]出F11进入跳转表:

  @ILT+560( f2@B@@EAEXXZ):

  00401235   jmp         B::f2 (00401860)

  @ILT+565( _Iput@ $num_put@DV $ostreambuf_iterator@DU $char_traits@D@std@@@std@@@std@@KA AV $ostreambuf_iterator@DU $char_traits@D@std@@@2@V32@AAVios_base@2@DPADI@Z):

  0040123A   jmp         std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Iput (00404

  @ILT+570(_main):

   

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Ctime函数 在ACM中的应用 下一篇局部类实现C++的闭包

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: