多态是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.当出现父类指针或引用指向子类对象时,子类中继承的虚基类指针表中函数会被子类函数重写.