面试题答案
一键面试1. 通过类实现多态的方式
在C++ 中,通过基类指针或引用指向派生类对象来实现多态。基类中定义虚函数,派生类重写这些虚函数。当通过基类指针或引用调用虚函数时,会根据实际指向的对象类型来决定调用哪个类的虚函数版本,从而实现多态。
2. 虚函数、纯虚函数以及虚表的作用
- 虚函数:在基类中使用
virtual
关键字声明的函数,允许派生类重写该函数。虚函数为多态提供了基础,使得通过基类指针或引用调用函数时,能够根据对象的实际类型动态绑定到合适的函数版本。 - 纯虚函数:是一种特殊的虚函数,在声明时初始化为 0 (
virtual void func() = 0;
)。包含纯虚函数的类为抽象类,不能实例化对象。纯虚函数主要用于定义接口,强制派生类必须重写该函数,进一步规范多态行为。 - 虚表:每个包含虚函数的类都有一个虚表(Virtual Table,简称 vtable)。虚表是一个函数指针数组,存储了类中虚函数的地址。当创建一个对象时,对象内部会有一个虚表指针(vptr),指向该类的虚表。在运行时,通过对象的虚表指针找到虚表,进而根据虚表中存储的函数地址调用合适的虚函数,实现动态绑定。
3. 代码示例
#include <iostream>
// 基类
class Animal {
public:
// 虚函数
virtual void speak() {
std::cout << "Animal speaks" << std::endl;
}
};
// 派生类
class Dog : public Animal {
public:
// 重写基类的虚函数
void speak() override {
std::cout << "Dog barks" << std::endl;
}
};
// 派生类
class Cat : public Animal {
public:
// 重写基类的虚函数
void speak() override {
std::cout << "Cat meows" << std::endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->speak(); // 调用 Dog 的 speak 函数
animal2->speak(); // 调用 Cat 的 speak 函数
delete animal1;
delete animal2;
return 0;
}
在上述代码中,Animal
类中的 speak
函数是虚函数。Dog
和 Cat
类继承自 Animal
类,并分别重写了 speak
函数。在 main
函数中,通过 Animal
指针指向不同派生类对象,调用 speak
函数时,实现了根据对象实际类型的动态绑定,展示了多态性。