多态是C++面向对象三大特性之一
多态分为两类
- 静态多态(重载): 函数重载 和 运算符重载属于静态多态,复用函数名
- 动态多态(重写): 派生类和虚函数实现运行时多态
静态多态和动态多态区别:
- 静态多态的函数地址早绑定 - 编译阶段确定函数地址
- 动态多态的函数地址晚绑定 - 运行阶段确定函数地址
下面通过案例进行讲解多态
class Animal { public: //Speak函数就是虚函数 //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。 virtual void speak() { cout << "动物在说话" << endl; } }; class Cat :public Animal { public: void speak() { cout << "小猫在说话" << endl; } }; class Dog :public Animal { public: void speak() { cout << "小狗在说话" << endl; } }; //我们希望传入什么对象,那么就调用什么对象的函数 //如果函数地址在编译阶段就能确定,那么静态联编 //如果函数地址在运行阶段才能确定,就是动态联编 void DoSpeak(Animal & animal) { animal.speak(); } // //多态满足条件: //1、有继承关系 //2、子类重写父类中的虚函数 //多态使用: //父类指针或引用指向子类对象 void test01() { Cat cat; DoSpeak(cat); Dog dog; DoSpeak(dog); } int main() { test01(); system("pause"); return 0; }
总结:
多态满足条件
- 有继承关系
- 子类重写父类中的虚函数
多态使用条件
- 父类指针或引用指向子类对象
多态的好处
1.可替换性(substitutability):多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility):多态对代码具有可扩充性。增加新的子类不但不影响已存在类反而更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability):向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
4.简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。 总结有利于代码的维护和拓展。
重写和重载的区别
重写:函数返回值类型 函数名 参数列表 完全一致称为重写
重载: 不同参数列表(类型,个数,顺序)的同名函数根据,参数列表决定调用哪个函数.
重写原理:
1.基类加上virtual关键词的时候,基类中包含一个虚基类指针,指向虚基类指针表,表中是基类函数
2.当出现父类指针或引用指向子类对象时,子类中继承的虚基类指针表中函数会被子类函数重写.