面试题答案
一键面试虚函数的函数调用过程
- 编译阶段:编译器在编译基类时,会为包含虚函数的类创建一个虚函数表(Virtual Table,简称 vtable)。虚函数表是一个数组,其中每个元素是一个指向虚函数的指针。同时,编译器会在每个包含虚函数的类对象中添加一个隐藏成员,即虚函数表指针(vptr),这个指针指向该类的虚函数表。
- 运行阶段:当通过基类指针指向派生类对象时,根据指针所指向对象的实际类型(这里是派生类类型),找到对应的虚函数表。然后,根据虚函数在虚函数表中的索引,找到实际要调用的虚函数的地址,进而调用该虚函数。这样就实现了动态绑定,也就是多态。
代码示例
#include <iostream>
// 基类
class Base {
public:
// 虚函数
virtual void print() {
std::cout << "This is Base class." << std::endl;
}
};
// 派生类
class Derived : public Base {
public:
// 重写基类的虚函数
void print() override {
std::cout << "This is Derived class." << std::endl;
}
};
int main() {
Base* basePtr;
Base baseObj;
Derived derivedObj;
// 基类指针指向基类对象
basePtr = &baseObj;
basePtr->print();
// 基类指针指向派生类对象
basePtr = &derivedObj;
basePtr->print();
return 0;
}
在上述代码中,Base
类包含一个虚函数 print
。Derived
类继承自 Base
类并重写了 print
函数。在 main
函数中,通过 Base
类指针分别指向 Base
类对象和 Derived
类对象,并调用 print
函数,展示了多态特性。