研究过虚函数表的人都知道c++的多态是来自于虚函数表的函数指针覆盖,那么子类的虚函数指针覆盖了虚函数表中相应位置的父类虚函数指针后,那是怎么调用父类的虚函数的呢?
即有如下继承关系:
class fa{
public:
virtual void show(){cout << "fa" << endl;}
};
class son : public fa{
public:
void show(){cout << "son" << endl;}
};
对函数指针改下名:
typedef void (*func)(void);
现在有如下调用:
int main()
{
son boy;
fa * ptrfa;
ptrfa = &boy;
fa one;
fa two;
/******测试信息******/
printf("子类show函数地址%x\n", *(int *)*(int *)&boy);
printf("父类show函数地址%x\n", *(int *)*(int *)&one);
printf("父类show函数地址%x\n", *(int *)*(int *)&two);
int showptr = 0x42d970; //这个值反汇编得来的,每次编译可能不同,这是fa::show函数的真正内存所在
func fff;
memcpy((char *)&fff, (char*)&showptr, sizeof(int));
fff();
/************/
//如下调用
(*ptrfa).fa::show();
return 0;
}
那么(*ptrfa).fa::show()这一行是怎么找到父类的show呢?不是说好的被子类的show覆盖了吗?
反汇编走一波,
可以发现,编译器直接调用存放在文本去的fa::show函数,根本没有虚函数表什么事......
总结:父类的虚函数被子类覆盖后,若指针强行调用父类的虚函数,编译器直接帮你在函数所在区找到函数,直接调用call,简单暴力而优雅......