一句话总结
父类写 virtual,子类重写,用父类指针/引用调用子类对象。
一、实现多态的 4 个必须条件
- 必须有继承关系(子类继承父类)
- 父类中必须将函数声明为 virtual(虚函数)
- 子类必须重写(override)这个虚函数
- 必须用 父类指针 / 父类引用 指向子类对象 调用函数
满足这 4 条,运行时就会自动调用子类版本 → 这就是多态。
二、最简代码示例(一看就懂)
cpp
#include <iostream>
using namespace std;
// 1. 父类
class Animal {
public:
// 2. 父类写 virtual
virtual void speak() {
cout << "动物叫" << endl;
}
};
// 3. 子类继承
class Dog : public Animal {
public:
// 4. 子类重写虚函数
void speak() override {
cout << "汪汪汪" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "喵喵喵" << endl;
}
};
// 测试:父类指针指向不同子类
int main() {
Animal* p1 = new Dog();
Animal* p2 = new Cat();
p1->speak(); // 输出 汪汪汪
p2->speak(); // 输出 喵喵喵
return 0;
}
运行结果:
汪汪汪
喵喵喵
同一个指针类型,调用同一个函数,执行不同逻辑 → 这就是多态。
三、最关键的 3 个考点(面试必问)
1. 为什么要加 virtual?
不加 virtual → 编译期确定函数地址(静态绑定)
加 virtual → 运行期查找函数地址(动态绑定)
2. 什么是重写(override)?
- 函数名、参数、返回值 完全一样
- 父类必须是虚函数
3. 析构函数为什么要写成 virtual?
如果父类指针指向子类对象,delete 时
- 析构不是 virtual → 只调用父类析构,内存泄漏
- 析构是 virtual → 先调用子类析构,再调用父类
正确写法:
cpp
virtual ~Animal() {}
四、最精炼背诵版(面试直接说)
- 建立继承关系
- 父类提供虚函数
- 子类重写虚函数
- 用父类指针或引用指向子类对象,调用同名函数