携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
1.多态的分类
多态分为两类:
- 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
- 动态多态: 派生类和虚函数实现运行时多态
静态多态和动态多态区别:
- 静态多态的函数地址早绑定 - 编译阶段确定函数地址
- 动态多态的函数地址晚绑定 - 运行阶段确定函数地址
2.多态的作用
多态是C++面向对象三大特性之一
-
多态就是多种形态:函数重载就是让函数名有多种形态进行表现出来,由于我们传进的参数个数不同,参数不同,类型不同,顺序不同。
-
运算符重载就是让运算符用多种形态来表现出来。
-
但是我们在C++中所说的多态指的是动态的多态。
3.重载和重写
函数重载和重写不一样:
- 重载:函数名相同,但是参数不相同。
- 重写:函数返回值、函数名、参数列表都相同。
4.实例讲解
#include<iostream>
using namespace std;
class Fath
{
public:
//Speak函数就是虚函数
//函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。
//virtual
void spr()
{
cout << "父类" << endl;
}
};
class Son1 :public Fath
{
public:
void spr()
{
cout << "子类1" << endl;
}
};
class Son2 :public Fath
{
public:
void spr()
{
cout << "子类2" << endl;
}
};
//我们希望传入什么对象,那么就调用什么对象的函数
//如果函数地址在编译阶段就能确定,那么静态联编
//如果函数地址在运行阶段才能确定,就是动态联编
void DoSpr(Fath & fath)
{
fath.spr();
}
//
//多态满足条件:
//1、有继承关系
//2、子类重写父类中的虚函数
//多态使用:
//父类指针或引用指向子类对象
void test()
{
Son1 son1;
DoSpr(son1);
Son2 son2;
DoSpr(son2);
}
int main() {
test();
system("pause");
return 0;
}
输出:
父类 父类 请按任意键继续. . .
结论:
- C++中允许父子之间的类型转换,不需要做强制类型转换。
- 父类的引用或者指针可以直接指向子类的那个对象。
- 原因是:现在这个函数的地址是早绑定.
- 地址早绑定,在编译阶段确定函数地址。
- 如果想执行让子类说话,那么这个函数地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定。
class Fath
{
public:
//Speak函数就是虚函数
//函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。
virtual void spr()
{
cout << "父类" << endl;
}
};
输出:
子类1 子类2 请按任意键继续. . .
结论:
- 动态多态满足条件:
1.有继承关系 2.子类重写父类的虚函数
- 动态多态的使用:
父类的指针或者引用 指向子类对象