多态性可以简单地概括为“一个接口,多种方法”,c++多态整体可以划分为2种:静态多台与动态多态。
二者最大的差别:
静态多态是编译器在编译期间完成的,编译器会根据实参类型来选择调用合适的函数,如果有合适的函数可以调用就调,没有的话就会发出警告或者报错。
动态多态是是在程序运行时根据基类的引用(指针)指向的对象来确定自己具体该调用哪一个类的虚函数。
动态多态的条件:
●基类中必须包含虚函数,并且派生类中一定要对基类中的虚函数进行重写。
●通过基类对象的指针或者引用调用虚函数。
重写 :
(a)基类中将被重写的函数必须为虚函数(上面的检测用例已经证实过了)
(b)基类和派生类中虚函数的原型必须保持一致(返回值类型,函数名称以及参数列表),协变和析构函数(基类和派生类的析构函数是不一样的)除外
(c)访问限定符可以不同
协变:基类(或者派生类)的虚函数返回基类(派生类)的指针(引用)
那些函数不能定义为虚函数?
1)友元函数,它不是类的成员函数
2)全局函数
3)静态成员函数,它没有this指针
3)构造函数,拷贝构造函数,以及赋值运算符重载(可以但是一般不建议作为虚函数)
静态多态与动态多态的对比:
静态多态:
优点:
- 由于静多态是在编译期完成的,因此效率较高,编译器也可以进行优化;
- 有很强的适配性和松耦合性,比如可以通过偏特化、全特化来处理特殊类型;
- 最重要一点是静态多态通过模板编程为C++带来了泛型设计的概念,比如强大的STL库。
缺点:
- 由于是模板来实现静态多态,因此模板的不足也就是静多态的劣势,比如调试困难、编译耗时、代码膨胀、编译器支持的兼容性
- 不能够处理异质对象集合
动态多态:
优点:
- OO设计,对是客观世界的直觉认识;
- 实现与接口分离,可复用
- 处理同一继承体系下异质对象集合的强大威力
缺点:
- 运行期绑定,导致一定程度的运行时开销;
- 编译器无法对虚函数进行优化
- 笨重的类继承体系,对接口的修改影响整个类层次;
不同点:
- 本质不同,静态多态在编译期决定,由模板具现完成,而动态多态在运行期决定,由继承、虚函数实现;
- 动态多态中接口是显式的,以函数签名为中心,多态通过虚函数在运行期实现,静态多台中接口是隐式的,以有效表达式为中心,多态通过模板具现在编译期完成
相同点:
- 都能够实现多态性,静态多态/编译期多态、动态多态/运行期多态;
- 都能够使接口和实现相分离,一个是模板定义接口,类型参数定义实现,一个是基类虚函数定义接口,继承类负责实现;
参考:
https://blog.csdn.net/qq_39412582/article/details/81628254
https://blog.csdn.net/hackbuteer1/article/details/7475622
https://www.cnblogs.com/Leo_wl/p/3667870.html