多态

Posted 小羊教你来编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多态相关的知识,希望对你有一定的参考价值。

在这里插入图片描述

目录:

一.多态概念

多态其实我们可以理解为: 人们去动物园买票的时候,大家买的都是票,但是每个人的价格是不一样的,学生可以买学生票,成人只能买成人票,还有残疾人票,这就是对于多态的理解,每个人买的都是票,可是每个人的价格是不一样的,这就体现了多态,对于同一个东西获取到不同的状态,其实就是多态的体现.

二.多态的定义/实现

1.多态的构成条件

在这里插入图片描述

构成多态的两个必要条件:

1.必须通过基类的指针或者引用i调用虚函数

2.被调用的函数必须是虚函数,且派生类对于基类的虚函数进行重写

2.虚函数的重写

1)构成

在这里插入图片描述

如果在派生类中不加virtual关键字的话,也可以构成重写 ,因为在继承的时候,会直接将基类中的Virtual直接继承过来,但是不是很规范,不建议使用!

2)函数重写的两个例外:

(1)协变

派生类重写虚函数的时候,和基类虚函数的返回值类型不同
1.基类返回基类对象的指针或引用
2.派生类返回派生类对象的指针或引用
在这里插入图片描述

(2)析构函数的重写

1.如果基类的析构函数为虚函数,只要派生类的析构函数定义了,有没有加vritual都会构成重写.
2.虽然基类和派生类的函数名不同,其实编译器内部对其进行了特殊处理,析构函数名称统一为destructor
在这里插入图片描述
构成重写后,在delete调用析构函数的时候,才能形成多态,保证p1和p2的正常调用析构函数

3)C++11 final / override

(1)final:修饰虚函数,表示该虚函数不能被继承

在这里插入图片描述

(2)override:检查派生类中是否重写基类的某个虚函数,没有重写则会报错

在这里插入图片描述

4)重载/覆盖/隐藏的对比

在这里插入图片描述

三.抽象类

1.概念

1.在一个类的虚函数后面加上 =0,这个函数就成为纯虚函数.包含纯虚函数的这个类就叫做抽象类,
2.抽象类不能实例化出对象,派生类继承后也不能实例化出对象
3.只有将其纯虚函数进行重写,才能实例化出对象来

2.通过代码理解

在这里插入图片描述

四.多态的原理

1.虚函数表

在这里插入图片描述

一个含有虚函数的类中至少都有一个虚函数表指针,因为虚函数的地址被放到虚函数表中,虚函数表也称为虚表.

1.虚函数存在虚表,虚表存在对象中
2.虚表中存的是虚函数指针,不是虚函数
3.虚函数和普通函数一样存在于代码段

2.多态的原理

步骤:

1.在红色箭头可以看出,在指向mike对象时,p->BuyTicket()在Mike的虚表中找到对应的虚函数Person::BuyTicket进行使用.

2.在绿色箭头看出来,在指向Johnson对象时,p->BuyTicket(),在Johnson的虚表中找到对应的Student::BuyTicket进行使用.

在这里插入图片描述
满足多态的条件:
----1.虚函数覆盖
----2.对象的指针或引用调用虚函数

多态以后的函数调用,不是在编译的时候确定的,是运行起来到对象中找到的.

3.静态绑定/动态绑定

静态绑定: 又叫做前期绑定,在程序编译期间确定了程序的行为,也是静态多态

动态绑定: 后期绑定,在程序运行期间,根据拿到的类型确定程序的具体行为,从而调用具体的函数,称为动态多态

五.单继承和多继承的虚函数表

1.单继承

在这里插入图片描述

监视窗口中我们发现看不见func3和func4。这里是编译器的监视窗口故意隐藏了这两个函数,
也可以认为是他的一个小bug。

2.多继承

在这里插入图片描述

多继承派生类的未重写的虚函数放在第一个继承基类部分的虚函数表中

这就是对于多态的总结,后期如果有更深的理解会继续更新.

以上是关于多态的主要内容,如果未能解决你的问题,请参考以下文章

多态性的基因多态性

多态与多态性

多态分为哪两中

多态与重载

C++多态底层剖析

C++多态底层剖析