面试题答案
一键面试可能遇到的特殊情况
- 多个虚函数表:由于C++多继承,类C可能会有多个虚函数表。这是因为类A和类B各自可能有独立的虚函数表,类C需要分别维护来自A和B的虚函数表。例如,当类A和类B都有不同的虚函数集时,类C为了能够正确实现多态,就需要有两个虚函数表指针分别指向不同的虚函数表。
- 虚函数表指针的布局:虚函数表指针在类C对象中的布局可能会变得复杂。在单继承中,虚函数表指针通常在对象布局的开始位置,但在多继承下,虚函数表指针的相对位置可能取决于编译器实现。这可能导致在分析虚函数表结构时,需要额外注意指针位置。
通过GCC选项获取并分析虚函数表结构
- GCC选项:使用
-fdump-class-hierarchy
选项,GCC会生成一个包含类层次结构和虚函数表信息的文件。例如,假设源文件名为main.cpp
,编译命令为g++ -fdump-class-hierarchy main.cpp
。这会生成一个以.o
文件为基础的*.classdump
文件,其中包含详细的类结构信息。 - 代码示例:
#include <iostream>
class A {
public:
virtual void funcA() {
std::cout << "A::funcA" << std::endl;
}
};
class B {
public:
virtual void funcB() {
std::cout << "B::funcB" << std::endl;
}
};
class C : public A, public B {
public:
void funcA() override {
std::cout << "C::funcA" << std::endl;
}
void funcB() override {
std::cout << "C::funcB" << std::endl;
}
};
int main() {
C c;
A* a = &c;
B* b = &c;
a->funcA();
b->funcB();
return 0;
}
编译后查看生成的*.classdump
文件,可以看到类似如下信息:
Class C
size=16 align=8
base size=8 base align=8
C (0x7f87c9e16140) 0
vptr[0] (subobject @0) = &_ZTV1A
vptr[1] (subobject @8) = &_ZTV1B
A (0x7f87c9e16140) 0
B (0x7f87c9e16148) 8
从上述信息可以看出,类C有两个虚函数表指针,分别对应类A和类B的虚函数表。第一个虚函数表指针vptr[0]
指向类A的虚函数表&_ZTV1A
,第二个虚函数表指针vptr[1]
指向类B的虚函数表&_ZTV1B
。通过这种方式,可以分析类C在多继承下的虚函数表结构。