派生类的虚函数列表
原创
©著作权归作者所有:来自51CTO博客作者wx6405b2c488d4e的原创作品,请联系作者获取转载授权,否则将追究法律责任
我们知道,每个具有虚函数的类中都有一张虚函数表,在rdata中用以记录每个类中虚函数列表,或者说虚函数的地址,那么如果是继承关系的类,对于其基类中函数虚函数的派生类,其虚函数表又是怎样的呢?下面看下C++源代码和反汇编的对比
#include "stdafx.h"
#include
using namespace std;
class A
{
public:
virtual void f(){cout<<"A::m\n";}
};
class B
{
public:
virtual void g(){cout<<"B::g\n";}
virtual void f(){cout<<"B::f\n";}
};
class C:public A,public B
{
public:
void f(){cout<<"C::f\n";}
virtual void gh(){cout<<"dsada\n";}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* a=new A();
B* b=new B();
C* c=new C();
a->f();
b->f();
b->g();
c->f();
c->gh();
return 0;
}
.rdata:00402148 const A::`vftable' dd offset A::f(void) ; DATA XREF: _wmain+14o
.rdata:0040214C dd offset const B::`RTTI Complete Object Locator'
.rdata:00402150 const B::`vftable' dd offset B::g(void) ; DATA XREF: _wmain+2Bo
.rdata:00402150 ; _wmain+42o
.rdata:00402154 dd offset B::f(void)
.rdata:00402158 dd offset const C::`RTTI Complete Object Locator'{for `A'}
.rdata:0040215C const C::`vftable'{for `A'} dd offset C::f(void) ; DATA XREF: _wmain+49o
.rdata:00402160 dd offset C::gh(void)
.rdata:00402164 dd offset const C::`RTTI Complete Object Locator'{for `B'}
.rdata:00402168 const C::`vftable'{for `B'} dd offset B::g(void) ; DATA XREF: _wmain+4Fo
.rdata:0040216C dd offset [thunk]:C::f`adjustor{4}' (void)
从上面我们可以看到,类A和类B具有虚函数列表,但是对于多重继承的类C他的虚函数列表则有些不同,可以看到类C的虚函数列表分成了两部分,分别是基类A和B的一部分,对于基类A,它是有一个C::f覆盖了基类A中的f函数,除此之外还有C自己的gh()函数,而对于派生自类B中的那一部分,没有覆盖的基类B的函数g则是记录B的函数地址,而对于f()函数的前民有一个thunk修饰,thunk的解释如下在多重继承的情况下,查看虚函数表时,要准备遭遇一个不是指向虚函数表而是指向修改this指针的代码的指针,修改指针的目的在于使他指向从中得到"替换函数"的实例,在这里,也就是说要将类C中的继承类B的虚函数列表部分中的函数f替换成类C本身的f函数地址!