在 C++ 中,多态(Polymorphism)是指允许不同类的对象对同一消息做出响应的能力,即同一个函数或方法在不同对象中有不同的行为。C++ 支持两种主要的多态形式:静态多态(也称为编译时多态)和动态多态(也称为运行时多态)。
静态多态(编译时多态)
静态多态主要通过函数重载(Overloading)、运算符重载(Operator Overloading)和模板(Templates)实现,它们在编译时确定具体的行为。
-
函数重载:同一个函数名,但参数类型或数量不同,编译器根据函数签名来决定调用哪个函数。
void func(int a) {} void func(double a) {} // 编译器会根据参数类型选择正确的 func 函数
-
运算符重载:允许为自定义类型定义运算符的行为,如重载
+
运算符。class MyType { public: MyType operator+(const MyType& other) const { // 实现加法 } };
-
模板:允许创建泛型函数和类,模板代码在编译时针对具体的类型实例化。
template <typename T> T add(T a, T b) { return a + b; } // 调用 add(3, 4) 会生成 int 类型的模板实例 // 调用 add(3.0, 4.0) 会生成 double 类型的模板实例
静态多态是在编译时决定的,因此也被称为早期绑定(Early Binding)。
动态多态(运行时多态)
动态多态是通过虚函数(Virtual Functions)实现的,它允许程序在运行时决定调用哪个函数实现。这是 C++ 支持的面向对象特性之一。
-
虚函数:在基类中使用
virtual
关键字声明函数,允许派生类重写(Override)该函数。class Base { public: virtual void show() { std::cout << "Base show" << std::endl; } }; class Derived : public Base { public: void show() override { std::cout << "Derived show" << std::endl; } };
-
基类指针或引用:通过基类的指针或引用调用虚函数,实现多态行为。
Base* basePtr = new Derived(); basePtr->show(); // 运行时调用 Derived::show() delete basePtr;
动态多态涉及到运行时的动态绑定(也称为晚期绑定,Late Binding),因此也被称为动态绑定。它要求至少有一个虚函数,并且通常与类层次结构一起使用。
区别:
- 时间:静态多态在编译时决定,而动态多态在运行时决定。
- 绑定:静态多态是早期绑定,动态多态是晚期绑定。
- 用例:静态多态适用于函数重载和模板编程,动态多态适用于面向对象编程中的继承和多态。
- 性能:静态多态没有运行时开销,而动态多态由于需要运行时查找,可能会有轻微的性能开销。
多态是 C++ 以及其他面向对象编程语言的重要特性,它提高了代码的灵活性和可重用性。