面试题答案
一键面试确保多态性正确实现的方法
- 在基类中声明虚函数:在
A
类中声明虚函数,例如:
class A {
public:
virtual void virtualFunction() = 0; // 纯虚函数示例,也可以是普通虚函数
};
- 在派生类中重写虚函数:
B
类、C
类和D
类都要重写该虚函数,使用override
关键字明确标识重写(C++11及以后),以提高代码的可读性和编译器的错误检查能力。
class B : public A {
public:
void virtualFunction() override {
// 实现代码
}
};
class C : public B {
public:
void virtualFunction() override {
// 实现代码
}
};
class D : public C {
public:
void virtualFunction() override {
// 实现代码
}
};
- 通过指针或引用调用虚函数:在使用类对象时,通过基类指针或引用调用虚函数,以确保运行时多态性的正确实现。
A* ptr = new D();
ptr->virtualFunction(); // 调用D类的virtualFunction
delete ptr;
内存布局变化
- 增加虚函数表指针:如果基类
A
中有虚函数,那么A
类对象的内存布局中会增加一个虚函数表指针(vptr),指向虚函数表(vtbl)。虚函数表是一个函数指针数组,存放着类中虚函数的地址。 - 派生类继承虚函数表指针:
B
、C
、D
类对象同样会继承这个虚函数表指针。当B
、C
、D
类重写虚函数时,虚函数表中的相应函数指针会被替换为派生类中重写函数的地址。 - 内存布局扩展:随着类层次结构的加深,派生类可能会增加自己的数据成员,这会导致对象的内存布局在继承的基础上进一步扩展。例如,
D
类对象的内存布局会包含A
、B
、C
类的数据成员以及D
类自身的数据成员,同时还有虚函数表指针。
总之,通过正确声明和重写虚函数,并使用指针或引用调用虚函数,可以确保多态性的正确实现;而多层继承会使对象的内存布局在继承基类成员的基础上不断扩展,同时虚函数表指针会贯穿整个类层次结构,用于实现运行时多态。