C++多态编程:从原理到实战
一、多态核心概念1. 什么是多态同一个行为不同对象有不同实现。父类引用 / 指针 指向 子类对象调用函数时执行子类重写的版本。2. 多态价值降低耦合代码高扩展父类统一接口子类自由实现新增子类无需修改原有业务代码符合开闭原则3. 实现多态的三大必要条件必须存在继承关系父类函数必须加virtual 虚函数父类指针 / 引用 指向 子类对象向上转型二、静态绑定 动态绑定静态绑定早绑定编译阶段确定函数地址普通成员函数默认都是静态绑定。动态绑定晚绑定运行阶段根据真实对象类型匹配函数虚函数触发动态绑定 → 产生多态。三、虚函数 virtual 基础语法父类声明虚函数子类重写该函数即可构成多态。virtual 返回值 函数名(参数);完整多态演示#include iostream using namespace std; // 父类 class Animal { public: // 虚函数 virtual void speak() { cout 动物发出声音 endl; } }; // 子类Dog class Dog : public Animal { public: // 重写虚函数 void speak() { cout 小狗汪汪叫 endl; } }; // 子类Cat class Cat : public Animal { public: void speak() { cout 小猫喵喵叫 endl; } };向上转型 多态调用// 父类指针指向子类对象 void doSpeak(Animal *a) { a-speak(); } int main() { Dog d; Cat c; doSpeak(d); doSpeak(c); return 0; }输出小狗汪汪叫 小猫喵喵叫同一接口speak()不同子类不同表现多态生效。四、函数重写override规则子类函数与父类函数名、参数、返回值完全一致父类必须是 virtual 虚函数子类可加override关键字显式标记编译器校验void speak() override;重写 / 重载 / 隐藏 三者区分重载同类中同名不同参编译绑定隐藏继承中子类同名函数屏蔽父类无 virtual重写继承 虚函数运行绑定实现多态五、向上转型 向下转型1. 向上转型多态核心常用子类对象 赋值给 父类指针 / 引用语法安全、自动转换多态全部依赖它。Animal* a new Dog;2. 向下转型不安全少用父类指针强制转回子类需要手动强转容易越界。Dog* d (Dog*)a;六、虚析构函数工程必踩坑当父类指针指向子类堆对象delete释放时若析构非虚只调用父类析构子类资源不释放 → 内存泄漏父类加virtual虚析构先子类析构再父类析构标准写法class Animal { public: virtual ~Animal(){} };只要类中有虚函数必须把析构写成虚析构。七、纯虚函数 抽象类1. 纯虚函数语法virtual void func() 0;2. 抽象类包含至少一个纯虚函数的类特点无法实例化对象只做父类定义统一接口子类必须重写所有纯虚函数否则子类也是抽象类示例class Shape { public: // 纯虚函数 virtual void getArea() 0; }; // 圆形子类必须实现纯虚函数 class Circle : public Shape { public: void getArea() override { cout 计算圆形面积 endl; } };八、多态底层简单理解含有虚函数的类内部会生成虚函数表 (vtable)对象自带虚表指针 (vptr)运行时通过虚表指针找到真实子类的函数地址实现运行时动态绑定九、高频易错点忘了写virtual只会触发隐藏没有多态重写时参数 / 返回值不一致不构成重写父类指针 delete 子类对象未写虚析构 → 内存泄漏抽象类直接实例化对象编译报错混淆重载、重写、隐藏三种概念十、今日核心总结多态三要素继承 虚函数 向上转型virtual 开启动态绑定运行时决定调用哪个函数子类重写虚函数实现个性化逻辑有虚函数必须搭配虚析构纯虚函数 → 抽象类用于定义标准接口