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

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

注:

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

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



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

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

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

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

好了划走吧。

相关推荐
jwn99910 分钟前
Laravel11.x新特性全解析
android·开发语言·php·laravel
feifeigo12312 分钟前
航天器交会的分布式模型预测控制(DMPC)MATLAB实现
开发语言·分布式·matlab
于先生吖12 分钟前
支持二开与商用,JAVA 漫剧付费观看系统完整源码
java·开发语言
环黄金线HHJX.13 分钟前
【从0到1】
开发语言·人工智能·算法·交互
曹牧14 分钟前
Java: 从oracle表中获取一组kv序列
java·开发语言·oracle
深邃-15 分钟前
【C语言】-数据在内存中的存储(1)
c语言·开发语言·数据结构·c++·算法
Lyyaoo.16 分钟前
【Java基础面经】Java 注解的底层原理
java·开发语言·python
妙蛙种子31117 分钟前
【Java设计模式 | 创建者模式】 抽象工厂模式
java·开发语言·后端·设计模式·抽象工厂模式
zhaoshuzhaoshu18 分钟前
Bash 与 Dash 的区别与联系
开发语言·bash·dash
xiaoye-duck23 分钟前
《算法题讲解指南:优选算法-字符串》--61.最长公共前缀,62.最长回文子串,63.二进制求和,64.字符串相乘
c++·算法·字符串