C++中的多态与虚函数的内部实现方法

2020-01-06 16:11:59王冬梅
C++,多态与虚函数 也就是说,由于C中的FunA重写(override)了A中的FunA,虚拟表中虚拟函数的地址也被重写了。 就是这样,这就是多态实现的内部机制。 我们再回到最初的问题:为什么*pB出了问题。 根据上边的结论,我们大胆地进行猜测:由于C是由A、B派生而来,所以objC有两个虚拟表,而由于表的顺序,pA、pC都指向了对应于A的虚拟表,而pB则指向了对应于B的虚拟表。做个实验来验证我们的猜想是否正确: 我们不改变A、B、C类,将问题中的main改一下:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
  C objC; 
  A *pA = &objA; 
  B *pB = &objC; 
  C *pC = &objC; 
   
  typedef void (*Fun)(void); 
 
  Fun fun = (Fun)*((int*)(*(int*)pC)); 
  fun();//第一个表第一个函数 
  fun = (Fun)*((int*)(*(int*)pC)+1); 
  fun();//第一个表第二个函数 
  fun = (Fun)*((int*)(*((int*)pC+1))); 
  fun();<span style="white-space:pre"> </span>//第二个表第一个函数 
  fun = (Fun)*((int*)(*(int*)pB)); 
  fun();//pB指向的表的第一个函数 
  return 0; 
}

哈哈,和我们的猜测完全一致:

FunA1C
FunA2
FunB
FunB 我们可以画出这样的虚函数图:         C++,多态与虚函数 暂且这样理解,编译器执行B *pB = &objC时不是仅仅是赋值,而是做了相应的优化,将pB指向了第二张虚表。 说了这么多,我是只是简单地解释了虚函数的实现原理,可究竟对象的内部的内存布局是怎样的?类数据成员与多个虚表的具体内存布局又是怎样的?编译器是如何在赋值的时候作了优化的呢?我在以后的时间里会讲一下。

以上就是小编为大家带来的C++中的多态与虚函数的内部实现方法全部内容了,希望大家多多支持ASPKU~


注:相关教程知识阅读请移步到C++教程频道。