zl程序教程

您现在的位置是:首页 >  其他

当前栏目

C++|对象模型|多继承虚机制实现

2023-03-15 22:02:32 时间

本文参考深度探索C++对象模型


我们常常使用基类指针指向派生类对象,那么,为什么基类指针能够如此轻松的调用派生类的方法呢?在多继承的情况下,this指针必须经过调整,才能正确地找到虚表。下文为你介绍多继承模型下的指针偏移机制


指针偏移存在机制:

设一个多继承的类内存布局如下,单词代表对象首地址。(派生类假设无额外成员)

后[Derived[BASE1][BASE2]]前

有三种情况,指针会发生偏移。


使用基类指针指向派生类

赋值时:派生->基

派生类的指针转型为第二个基类指针。向前调整Base1长度以正确指向Base2。

调用时:基->派生

指向第二个基类的指针,调用派生类的虚函数。例如:对于Base1和Base2而言,如果Base2定义clone,Derived重写了clone,那么需要向后调整Base1长度以正确指向Derived object


使用派生类指针指向派生类

调用时:派生->基 指向派生类的指针,调用第二个基类继承来的虚函数。向前调整Base1长度以正确指向Base2 sub-object。


指针偏移实现机制:

1.赋值:转型

temp为已知Derived指针。

Base2 * pbase2 =temp ? temp + sizeof (Base1):0;

目的是防止temp==nullptr时,仍然出现偏移。

2.调用:

split functions

  • 函数较小时,产生两个函数,根据调用的指针类别判断是否需要调用有调整的函数
  • 函数较大时,产生多重进入点,函数体分为(1)调整this (2)执行自定义函数码,根据是否需要调整,通过thunks跳转至对应的进入点

address points:

虚函数期待获得的是引入虚函数的类对象的地址(而非派生类),这就是这个函数的address point。换而言之,它首先确保了转入的地址能够正确的指向对应的调用对象,此后再进行传递。