C++ 多态详解:编译时/运行时多态、函数重载、运算符重载、虚函数与覆盖
什么是 C++ 多态?
在 C++ 中,多态导致成员函数根据调用它的对象表现出不同行为。多态源自希腊语,意为“多种形态”。它发生在通过继承关联的类层级中。
例如,假设有 makeSound() 函数。猫调用它发出“喵”,牛调用它发出“哞”。

虽为同一函数,却在不同情境下行为不同。函数呈现多种形态,即实现了多态。
本教程你将学到:
- 多态的概念
- 多态的类型
- 编译时多态
- 函数重载
- 运算符重载
- 运行时多态
- 函数覆盖
- C++ 虚函数
- 编译时多态 vs 运行时多态
多态的类型
C++ 支持两种多态:
- 编译时多态
- 运行时多态

编译时多态
通过匹配参数数量和类型调用重载函数。信息在编译期已知,编译器在编译时选择正确函数。
编译时多态通过函数重载和运算符重载实现。
函数重载
同名函数参数不同(数量或类型)即构成重载。
示例 1:
#include <iostream> using namespace std; void test(int i) { cout << " The int is " << i << endl; } void test(double f) { cout << " The float is " << f << endl; } void test(char const *ch) { cout << " The char* is " << ch << endl; } int main() { test(5); test(5.5); test("five"); return 0; }
输出:

代码截图:

三个同名函数参数类型不同,实现了多态。
运算符重载
为 C++ 运算符定义新含义,改变其行为。如定义 + 拼接字符串。整数间仍作加法,字符串间则拼接。
示例 2:
#include<iostream> using namespace std; class ComplexNum { private: int real, over; public: ComplexNum(int rl = 0, int ov = 0) { real = rl; over = ov; } ComplexNum operator + (ComplexNum const &obj) { ComplexNum result; result.real = real + obj.real; result.over = over + obj.over; return result; } void print() { cout << real << " + i" << over << endl; } }; int main() { ComplexNum c1(10, 2), c2(3, 7); ComplexNum c3 = c1+c2; c3.print(); }
输出:

代码截图:


运行时多态
对象方法在运行时而非编译时被调用。通过函数覆盖实现,调用的函数在运行时确定。
函数覆盖
派生类给基类函数提供新定义,即覆盖基类函数。
示例:
#include <iostream> using namespace std; class Mammal { public: void eat() { cout << "Mammals eat..."; } }; class Cow: public Mammal { public: void eat() { cout << "Cows eat grass..."; } }; int main(void) { Cow c = Cow(); c.eat(); return 0; }
输出:

代码截图:

C++ 虚函数
虚函数是实现运行时多态的另一种方式。在基类中用 virtual 关键字声明,在派生类中重新定义。若虚函数类被继承,派生类重定义虚函数以适应需求。
示例:
#include <iostream> using namespace std; class ClassA { public: virtual void show() { cout << "The show() function in base class invoked..." << endl; } }; class ClassB :public ClassA { public: void show() { cout << "The show() function in derived class invoked..."; } }; int main() { ClassA* a; ClassB b; a = &b; a->show(); }
输出:

代码截图:

编译时多态 vs 运行时多态
| 编译时多态 | 运行时多态 |
|---|---|
| 又称早绑定或静态多态 | 又称晚绑定或动态多态 |
| 方法在编译时调用 | 方法在运行时调用 |
| 通过函数重载和运算符重载实现 | 通过函数覆盖和虚函数实现 |
| 示例:方法重载,同名不同参数数量或类型 | 示例:方法覆盖,同名同原型 |
| 执行更快,方法发现于编译期 | 执行较慢,方法发现于运行期 |
| 灵活性较低,编译期一切已知 | 灵活性高,运行期发现方法解决复杂问题 |
总结
- 多态意为多种形态。
- 发生在通过继承关联的类层级中。
- 多态使函数可根据调用对象表现不同行为。
- 编译时多态中,调用函数在编译期确定。
- 运行时多态中,调用函数在运行期确定。
- 编译时多态通过函数重载和运算符重载实现。
- 函数重载:同名函数参数不同(数量或类型)。
- 运算符重载:为 C++ 运算符定义新含义。
- 运行时多态通过函数覆盖实现。
- 函数覆盖:派生类给基类函数新定义。
C语言
- C++数组传递给函数实战指南
- C++ 运算符全解析:类型、示例与示例程序
- 掌握 C++ switch-case:语法、用法与实战示例
- C++ 动态数组分配实战指南:new/delete、初始化、扩容与内存管理
- C++ 运算符重载实战指南:语法、方法、限制与代码示例
- C++ 结构体详解:定义、初始化、指针、函数参数与局限性
- 掌握 C++ std::list:语法、函数与实战示例
- C++ 函数详解:从声明到调用的实战指南
- C++ Struct 与 Class 核心差异、语法及最佳实践
- C 语言 calloc() 详解:零初始化动态分配原理与实战案例
- C 语言 free() 函数实战指南:正确释放动态内存、防泄漏与避坑全解析
- Python strip() 方法完全指南:去除首尾空白与自定义字符实战