[C++]多态

时间:2024-07-13 09:52:00
一、多态概述

多态是面向对象编程(OOP)的一个重要特性,它允许我们使用统一的接口来处理不同类型的对象。简单来说,就是同一个操作作用于不同的对象时,可以有不同的解释和效果。在C++中,多态主要通过虚函数实现,分为静态多态(编译时多态)和动态多态(运行时多态)。

二、多态的作用

多态的主要作用是解决项目中的紧耦合问题,提供程序的可扩展性。通过多态,应用程序不必为每一个实现子类的功能调用编写单独的代码,提高了代码的复用性和可维护性。

三、多态发生的三个条件
  1. 有继承:子类继承自父类。
  2. 重写父类的虚函数:子类重写了父类中的虚函数。
  3. 父类指针(或引用)指向子类对象:通过父类的指针或引用来调用被重写的虚函数。
四、多态实现的原理

C++中的动态多态通过虚函数和虚函数表实现。编译器会为包含虚函数的类生成一个虚函数表(vtable),该表是一个函数指针数组,存放了类中所有虚函数的入口地址。类实例化成对象后,对象首地址处会存放一个指向虚函数表的指针(vptr)。当通过父类指针或引用调用虚函数时,会根据对象的实际类型(即运行时类型),在虚函数表中查找对应的函数指针,然后调用具体的实现代码。

五、静态多态与动态多态
  1. 静态多态(编译时多态):主要包括函数重载、模板和隐藏。
    • 函数重载:在同一个作用域内,名称相同的函数参数类型或参数个数不同。
    • 模板:编译时进行代码生成,根据传递的模板参数不同,生成不同的代码。
    • 隐藏:在子类中定义与父类同名同参数的函数,隐藏了父类的同名函数。
  2. 动态多态(运行时多态):通过虚函数实现,即在运行时根据对象的实际类型确定调用的函数。
六、虚函数与纯虚函数
  1. 虚函数:用virtual关键字修饰的类成员函数,允许在派生类中被重写。
  2. 纯虚函数:没有函数体的虚函数,用于定义接口,强制派生类重写该函数。纯虚函数的一般形式为virtual void functionName() = 0;
七、虚析构函数和纯虚析构函数
  1. 虚析构函数:当基类指针指向派生类对象时,通过基类指针删除对象时,会调用派生类的析构函数,然后调用基类的析构函数,确保对象被正确销毁。
  2. 纯虚析构函数:允许类成为抽象基类,强制派生类提供析构函数的实现。
八、重写、重载与重定义(隐藏)
  1. 重写(Override):派生类重写基类的虚函数。
  2. 重载(Overload):同一作用域内,函数名相同但参数类型或数量不同的函数。
  3. 重定义(隐藏,Name Hiding):在派生类中定义与基类同名的函数(无论参数是否相同),隐藏了基类的同名函数。
九、示例代码
#include <iostream>  
using namespace std;  
  
class People {  
public:  
    virtual void myFunction() {  
        cout << "父类的虚函数" << endl;  
    }  
    virtual ~People() {} // 虚析构函数  
};  
  
class Xishi : public People {  
public:  
    void myFunction() override { // C++11 引入 override 关键字  
        cout << "西施的虚函数" << endl;  
    }  
};  
  
void callFunction(People* p) {  
    p->myFunction();  
}  
  
int main() {  
    People* p = new Xishi();  
    callFunction(p); // 调用西施的虚函数  
    delete p;  
    return 0;  
}