面试题答案
一键面试- 编译器操作:
- 编译器在编译时,看到通过
A
类型指针调用func()
函数。由于func()
是虚函数,编译器不会直接生成调用具体函数的代码,而是生成通过虚函数表指针(vptr)间接调用函数的代码。 - 编译器为每个包含虚函数的类(这里的
A
、B
、C
)生成一个虚函数表(vtable)。虚函数表是一个函数指针数组,每个元素指向类中虚函数的实际实现。 - 在
A
的虚函数表中,func()
对应的表项指向A::func()
的实现。当B
覆盖func()
时,B
的虚函数表中func()
对应的表项指向B::func()
的实现。同理,C
的虚函数表中func()
对应的表项指向C::func()
的实现。 - 对于每个对象,编译器在对象的内存布局中添加一个虚函数表指针(vptr),该指针指向对应类的虚函数表。
- 编译器在编译时,看到通过
- 运行时操作:
- 当程序运行到通过
A
类型指针调用func()
时,首先根据该指针找到对应的对象。因为对象内存布局中第一个成员就是虚函数表指针(vptr),通过这个 vptr 找到对象所属类(这里是C
类)的虚函数表。 - 在
C
类的虚函数表中,找到func()
对应的函数指针。由于C
覆盖了func()
,虚函数表中func()
对应的指针指向C::func()
的实现。 - 最后,通过找到的函数指针调用
C::func()
函数。
- 当程序运行到通过