【C++打怪之路Lv14】- “多态“篇

🌈 个人主页:白子寰

🔥 分类专栏:重生之我在学Linux,C++打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~

💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)

目录

1.什么是多态?

2.多态的构成条件

1)多态的构成条件多态的构成条件)

2)什么是虚函数?什么是虚函数?)

3)什么是虚函数的(覆盖/重写)?什么是虚函数的(覆盖/重写)?)

虚函数重写的两个例外

①协变(了解)

②析构函数的重写

区别(不构成多态就是隐藏)

目的

参数列表(签名)要求

访问控制

多态性

[c++11 override 和 final](#c++11 override 和 final)

override

final

重载、覆盖(重写)、隐藏(重定义)的对比

重载

重写(覆盖)

重定义(隐藏)

抽象类

概念

多态的原理

虚函数表(虚表)

动态绑定与静态绑定

动态绑定

静态绑定

总结

多态的特点

[多态调用 VS 普通调用](#多态调用 VS 普通调用)


1.什么是多态?

概念:多种形态

具体来说:不同的对象去做同一个行为,结果不同(不同的人做同一件事情有不同的结果)
举个例子:
①不同的人去买票:成人买成人票;学生买学生票
②不同的动物叫,会产生不同的叫声



2.多态的构成条件

1)多态构成条件

2)什么是虚函数?

3)什么是虚函数的 覆盖 / 重写

虚函数的(覆盖/重写)有什么特征?

1)多态的构成条件

①虚函数的重写

重写它的实现,基类和派生类最好都加上virtual

②父类指针或引用调用虚函数

父类一定要加virtual,子类可加可不加(最好加上)


2)什么是虚函数?

有virtrual修饰的类成员函数

①virtual在函数的返回值前加
②只能用来非静态的成员函数,不能用来修饰全局函数


3)什么是虚函数的(覆盖/重写)?

没有virtual修饰的类成员函数

虚函数的(覆盖/重写)有什么特征?

有三同(函数名,返回值类型,函数类型参数)

重写是特殊的隐藏


虚函数重写的两个例外

①协变(了解)

基类和派生类虚函数 返回值类型不同


②析构函数的重写

基类与派生类析构函数 名字不同


区别(不构成多态就是隐藏)
目的

隐藏是为了在派生类中使用相同名称的成员,而与基类中的成员区分开来。
重写是为了在运行时能够根据对象的实际类型来调用正确的函数版本,实现多态。

**参数列表(签名)**要求

隐藏不要求签名相同,名称相同即可。
重写要求签名必须相同。

访问控制

隐藏可以发生在任何访问修饰符下 ,不需要基类成员是虚函数。
重写要求基类中的函数必须是虚函数,且通常情况下,重写的函数访问修饰符不能比基类中的更严格。

多态性

隐藏不会影响多态性。
重写是实现多态的必要条件


c++11 override 和 final

override

在派生类参数列表后面加,检查有没有重写


final

修饰虚函数,表示该虚函数不能再被重写

也可以修饰类,在父类名称后+final(表示它的子类不能继承这个父类)
不能被继承的方法:父类的构造函数变成私有


重载、覆盖(重写)、隐藏(重定义)的对比

重载

两个函数在同一作用域

函数名相同,参数不同

重写(覆盖)

两个函数分别在基类和派生类的作用域

三同

两个函数必须是虚函数

重定义(隐藏)

重写也是一种特殊的隐藏

两个函数分别再基类和派生类的作用域

函数名相同

两个基类和派生类的同名函数不构成重写就是重定义



抽象类

概念

包含纯虚函数的类叫抽象类

纯虚函数 :在函数的参数列表后 + "=0"

不能实例化出对象

只有重写纯虚函数,才能实例化出对象



多态的原理

为什么虚函数要放进虚表?

在虚表(函数指针数组)里面找对应函数,指向谁调用谁

虚函数表(虚表)

算字节时对齐后多算4个字节(86位情况下)【因为多了一个指针】
本质上是个指针数组
虚表在常量区代码段,
虚函数跟普通函数一样放在代码段,
虚表指针在对象里面

动态绑定与静态绑定

动态绑定

1.符合多态
2.被重写了是在不同的虚函数表里

静态绑定

不符合多态,编译时绑定,跟指向的对象无关



总结

多态的特点

看指向对象指向谁调用谁(指向哪个对象就调用哪个对象的虚函数)

多态调用 VS 普通调用

①多态调用,看指向对象类型,指向谁调用谁的虚函数
②普通调用,看调用者的类型,调用调用者的函数

注:

本篇文章所说的是动态的多态

静态的多态:通过函数重载或函数模板调用(在编译时确定)



***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。

等等等等一下,分享最近喜欢的一句话:

"做自己人生的福尔摩斯"。

我是白子寰 ,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!!

好了划走吧。

相关推荐
Re.不晚12 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会14 分钟前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香17 分钟前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??21 分钟前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
远望清一色37 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself1 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
凌云行者1 小时前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
凌云行者1 小时前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
杜杜的man1 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang