当出现虚函数时(不管几个),类需要增加4bytes,用来存储指向该类虚函数表头的指针,称为vp
class A
{
public:
int a;
virtual void fun(){cout<<1<<endl;}
virtual void fun2(){cout<<2<<endl;}
};
class B:public A
{
public:
void fun(){cout<<3<<endl;}
void fun2(){cout<<4<<endl;}
};
class C:public B
{
public:
void fun(){cout<<5<<endl;}
void fun2(){cout<<6<<endl;}
};
sizeof(A) 的值是8,4bytes是int a,4bytes是虚函数表指针。
A* pa = new A;
pa->fun();
执行过程:1.发现fun是虚函数,去找pa的vp(指向A的虚函数表),
2.跳转到A的虚函数表
3.并执行A::fun.fun是第一个虚函数(顺序跟基类虚函数声明顺序一致)
virtual table of A
|A::fun()的入口地址 |<-- A的虚函数表指针vp
|A::fun2()的入口地址|<-- vp+1
virtual table of B
|B::fun()的入口地址 |<-- B的虚函数表指针vp
|B::fun2()的入口地址|<-- vp+1
A* pa = new B;
pa->fun();
同样,执行过程:发现fun是虚函数,去找pa的vp(指向B的虚函数表),跳转到B的虚函数表,并执行B::fun
这样,靠对象里的存储的虚函数表指针来实现了多态。并且,一旦在基类A中声明了虚函数fun(参数表),子类以及孙类
中同名的函数(声明完全相同)都会成为虚函数,并且函数的入口地址在自己虚函数表中