面试题答案
一键面试虚函数表指针存储位置
在C++中,虚函数表指针(vptr)通常存储在对象内存布局的起始位置。对于一个包含虚函数的类,每个对象都会包含一个指向其所属类的虚函数表(vtable)的指针,这个指针就是虚函数表指针。
多个虚函数时的内存布局和调用机制
- 内存布局:当类中有多个虚函数时,虚函数表(vtable)是一个函数指针数组。每个虚函数在这个数组中占据一个位置,按照它们在类中声明的顺序排列。虚函数表指针指向这个虚函数表。
- 调用机制:当通过对象指针或引用调用虚函数时,首先会根据对象的虚函数表指针找到对应的虚函数表。然后,根据虚函数在表中的索引(基于其声明顺序)找到实际要调用的函数地址,并执行该函数。
多重继承时的内存布局和调用机制
- 内存布局:
- 当存在多重继承且基类中有虚函数时,派生类对象可能会包含多个虚函数表指针。每个直接基类若有虚函数,派生类对象中会有一个指向该基类虚函数表的指针。
- 派生类的虚函数会被合并到相应基类的虚函数表中。如果派生类重写了某个基类的虚函数,虚函数表中对应位置的函数指针会被替换为派生类中重写的函数地址。
- 调用机制:
- 调用虚函数时,首先根据对象的类型确定要使用哪个虚函数表指针。这通常取决于对象指针或引用的静态类型(如果是通过基类指针或引用调用)。
- 找到对应的虚函数表后,如同单一虚函数表的情况,根据虚函数在表中的索引找到实际要调用的函数地址并执行。例如,如果通过基类A的指针调用虚函数,就会使用与基类A相关的虚函数表;若通过基类B的指针调用,就会使用与基类B相关的虚函数表。