1. 多态
1.1 什么是多态
不同的对象(派生类和基类)执行同一个行为或事件产生的结果是不一样的,即多种状态。
同一个接口,不同的实现;使用不同的派生对象来调用同一个接口会产生不同的状态。且函数接口继承于父类,父类也是可以调用的。
例如:Person 为人,Student 继承了 Person 的派生类,二者均调用一个函数,产生了多种状态。这种情况是如何实现的呢?
1.2 构成多态的条件
通过父类指针或者引用调用虚函数。调用的函数必须是虚函数,且子类对虚函数完成重写。
多态调用与普通调用的区别:
- 多态调用:被调函数看指向的对象类型。
- 普通调用:看当前对象的类型。
虚函数
在成员函数前面加上关键字 virtual,并且基类的成员函数和派生类的成员函数的返回值、函数名字以及参数列表(类型、顺序、数量)相同。参数列表相同不包含形参的名字。

特例
派生类的函数可以不加 virtual,也可以实现虚函数(建议在使用的时候加上,好辨认)。
**协变:**虚函数的返回值可以是父类和子类的引用或者指针,当然自身的父子引用以及其他父子类的引用和指针均可以,父类的引用必须是父类,子类的引用必须是子类。(完全没有必要)
为什么派生类中的函数可以不加 virtual?因为在基类中的函数已经加入 virtual,表明此函数就是虚函数,派生类的继承继承这个函数的性质,在不加 virtual 的时候也是虚函数。
重写是对函数体的重新构建,其他的保持三同,重写还叫做覆盖。
重写(覆盖)与重定义(隐藏)
重写(覆盖)
复用基类虚函数的函数签名和返回值,提供函数更加具体的实现。在编译层面上是通过虚函数表关联的,被视为用同一个函数的不同形态,同一接口的不同行为。在派生类中的函数名字和基类相同的成员函数,不是重写就是重定义。
注:函数标签就是函数名、参数列表和成员函数的 const 限定符。
重定义(隐藏)
本质:派生类中只要存在与基类同名的函数,就会屏蔽基类中所有同名函数。
总结:
- 重写是'同一个函数的不同实现'(非新函数),依赖虚函数实现多态;
- 重定义是'同名的不同函数'(新函数),仅存在名称巧合,无多态支持。
1.3 析构函数的多态(重点)
C++ 的类中将析构函数的函数名统一处理为 destructor,为了让析构函数也构成多态。

但是特殊情况会造成内存泄漏。






