多态

多态

今天我们来学一下多态这个概念

为什么需要多态?

假如我们想要定义一个动物叫的函数,如果没有使用多态,那么将会是这样的

#include <iostream>
using namespace std;

// 定义狗类
class Dog {
public:
    // 狗的叫
    void bark() {
        cout << "小狗:汪汪汪~" << endl;
    }
};

// 定义猫类
class Cat {
public:
    // 猫的叫
    void meow() {
        cout << "小猫:喵喵喵~" << endl;
    }
};

// 定义鸡类
class Chicken {
public:
    // 鸡的叫
    void cluck() {
        cout << "小鸡:咯咯咯~" << endl;
    }
};

// 主函数:让不同动物叫
int main() {
    Dog dog;
    Cat cat;
    Chicken chicken;

    // 调用不同的函数,才能让不同动物叫
    dog.bark();
    cat.meow();
    chicken.cluck();

    return 0;
}

可以看到,代码是及其繁琐且复杂的,而且可读性也不强,所以我们引入了多态这一概念

实现多态的三个前提条件

  1. 必须存在继承关系(比如要写猫叫与狗叫的逻辑前提为猫和狗的父类为动物类)
  2. 必须有由父类指向的指针
  3. 子类必须重写父类的虚函数(virtual)

如果有不懂的词,不用着急,接下来会继续演示深入

虚函数

下面来介绍一下虚函数这一个概念
虚函数相当于是子类允许重写函数的开关,如果没有声明为虚函数,那么即使重写了,也无法触发多态
下面是使用虚函数实现多态的一个示例

class Animal { // 父类
public:
    virtual void cry() { // 虚函数
        cout << "动物的叫声" << endl;
    }
};

class Dog : public Animal { // 子类继承父类
public:
    // 正确重写:函数名、返回值、参数列表完全和父类一致
    void cry() {
        cout << "小狗:汪汪汪~" << endl;
    }
};

重写

子类定义一个和父类虚函数完全一致的函数,替换父类的默认实现,实现子类专属逻辑 —— 这是多态的核心行为
子类重写的函数,必须和父类虚函数满足 函数名相同、返回值相同、参数列表完全相同(个数、类型、顺序都一致),否则编译器会认为是子类新增函数,而非重写,无法触发多态。

重写检测

子类重写的可选写法:override 关键字(可加可不加)
C++11 新增 override 关键字,写在子类重写函数的末尾,强制编译器检查是否满足重写规则—— 如果不满足(比如函数名写错、参数不一致),编译器会直接报错,避免新手因笔误导致多态失效。

指针与引用

使用指针实现多态

anm* p1 = &a;
p1->cry();

输出

喵喵喵~

使用引用实现多态

void letAnimalCry(Animal& animal) {
    animal.cry();
}

输出

喵喵喵~

如果既不使用指针,也不使用引用,那么多态将会失效

动物叫   //(未触发多态)
posted @ 2026-02-04 19:50  努力的小xu  阅读(4)  评论(0)    收藏  举报