【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 普通调用

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

注:

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

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



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

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

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

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

好了划走吧。

相关推荐
唐诺6 分钟前
几种广泛使用的 C++ 编译器
c++·编译器
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
冷眼看人间恩怨1 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
信号处理学渣1 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客1 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin1 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
jasmine s1 小时前
Pandas
开发语言·python
biomooc2 小时前
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
开发语言·r语言
骇客野人2 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
black^sugar2 小时前
纯前端实现更新检测
开发语言·前端·javascript