面试题答案
一键面试1. 虚基类 X 在 W 对象内存布局中的存储
在这种复杂的虚基类继承结构中,虚基类 X 的数据成员在 W 对象的内存布局中只会出现一次,无论从多少条路径继承它。这是虚继承的关键特性,避免了数据成员的重复存储。
具体来说,W 对象的内存布局通常包含指向虚基类子对象(这里是 X)的指针(虚基表指针)。这个指针指向一个虚基表,虚基表中存储了虚基类 X 相对于 W 对象起始地址的偏移量。通过这种间接的方式,即使 W 从多个路径继承 X,也能确保 X 的唯一性。
2. 对访问权限的影响机制
- 成员访问:由于虚基类 X 是 public 继承(因为 X 的成员函数 print() 是 public),W 的对象可以直接访问 X 的 public 成员。例如,W 的对象可以调用 X 的 public 成员函数 print()。这种访问权限遵循 C++ 的继承访问控制规则,与普通继承类似,但由于虚继承保证了 X 的唯一性,不存在访问歧义。
- 继承链访问:在虚继承体系中,从 W 到 X 的继承路径是明确且唯一的,这使得编译器能够正确解析对 X 成员的访问。无论是通过 Y 还是 Z 的路径,对 X 成员的访问都是统一的,不会因为多重继承路径而产生访问冲突。
3. 对函数调用的影响机制
- 函数重写与动态绑定:Y 和 Z 分别重写了 X 的 print() 函数。当通过 W 的对象调用 print() 时,动态绑定机制会根据对象的实际类型来决定调用哪个版本的 print()。如果 W 的对象的实际类型是 W 本身,并且 Y 和 Z 对 print() 的重写不同,那么编译器会根据虚函数表来确定调用哪个版本。
- 虚函数表的作用:W 的对象有自己的虚函数表,虚函数表中存储了指向各个虚函数(包括从 X 继承而来并可能被重写的函数)的指针。在运行时,通过对象的虚函数表指针找到对应的虚函数表,进而找到要调用的函数版本。由于虚继承,从 X 继承的虚函数在虚函数表中的位置是固定且明确的,确保了正确的函数调用。