面试题答案
一键面试虚函数概念
虚函数是在基类中使用 virtual
关键字声明的成员函数。它提供了一种接口约定,允许派生类根据自身需求重写该函数,以实现不同的行为。
多态概念
多态是面向对象编程的重要特性之一,它允许通过基类指针或引用调用派生类中重写的虚函数,从而在运行时根据对象的实际类型来决定调用哪个函数版本,实现“一种接口,多种实现”。
通过虚函数实现多态的方式
- 在基类中声明虚函数。
- 派生类重写(override)基类的虚函数,函数签名(参数列表和返回类型)必须与基类中的虚函数完全一致(除了协变返回类型)。
- 通过基类指针或引用调用虚函数,此时将根据指针或引用所指向的实际对象类型,在运行时动态绑定到相应的函数版本。
虚函数表在多态实现过程中的作用举例
假设有如下代码:
#include <iostream>
class Base {
public:
virtual void func() {
std::cout << "Base::func()" << std::endl;
}
};
class Derived : public Base {
public:
void func() override {
std::cout << "Derived::func()" << std::endl;
}
};
int main() {
Base* ptr = new Derived();
ptr->func();
delete ptr;
return 0;
}
在上述代码中:
- 每个包含虚函数的类(如
Base
类)都有一个虚函数表(vtable)。虚函数表是一个数组,存储了类中虚函数的地址。 - 当对象创建时,对象内部会有一个指向虚函数表的指针(vptr)。
- 对于
Base
类对象,其 vptr 指向Base
类的虚函数表,表中存储了Base::func
的地址。 - 对于
Derived
类对象,其 vptr 指向Derived
类的虚函数表,由于Derived
重写了func
函数,表中存储的是Derived::func
的地址。 - 在
main
函数中,Base* ptr = new Derived();
创建了一个Derived
类对象并将其地址赋给Base
类型指针ptr
。当调用ptr->func()
时,通过ptr
中的 vptr 找到Derived
类的虚函数表,进而调用Derived::func
,实现了多态。虚函数表在这里起到了在运行时根据对象实际类型找到对应虚函数地址的关键作用。