多态【C/C++复习版】

目录

一、多态是什么?如何实现?

二、 什么是重写?有什么特点?

 三、什么是协变?

四、析构函数能实现多态吗?为什么要实现?

五、override和final的作用是什么?

六、 多态的原理是什么?虚表/虚函数表

七、虚表保存在哪里?

八、坑题

九、多态分几种?哪几种?

十、多继承+虚函数重写(多个父类的类会有几个虚表?)


一、多态是什么?如何实现?

多态:不同的对象调用一个同名函数时,实际调用的是不同的函数,会有不同的行为或结果,比如:高铁票买票时有学生票和成人票。

可以通过虚函数来实现:父类定义了虚函数(用virtual修饰的函数),子类重写该函数,通过基类的指针或引用来调用虚函数。

构成多态的两个条件:①重写了虚函数 ②通过父类的指针或引用调用虚函数

二、 什么是重写?有什么特点?

重写(覆盖)是指在派生类中有一个跟基类返回值,函数名,形参列表相同(缺省参数除外)的虚函数。

重写时,只是重写函数体的部分,函数头用的是父类的,也就是说,如果有的话,缺省参数也是用的父类的。派生类重写时,可以不加virtual。

 三、什么是协变?

虚函数返回值不同时,必须满足协变。协变的返回值可以不同,但协变的返回值必须是父子关系(不一定是当前的父子类,可以是任意别的父子类)的指针或引用(同时是指针或同时是引用)。

四、析构函数能实现多态吗?为什么要实现?

1)析构函数加上virtual关键字是可以实现多态的,虽然表面上看他们名字不同,但实际上编译器会将析构函数的名字统一处理成destrutor。

2)如果析构函数不实现多态,会出现下面的问题:一个父类指针类型有可能指向父类,也有可能指向子类,实现多态才能在delete这个指针时,调用它真正指向的类型的析构函数。

五、override和final的作用是什么?

1)override关键字用于显式地声明一个成员函数是重写其基类中的虚函数,以确保正确的多态行为,可以增加代码的可读性,并且在子类中改写基类的虚函数时会让编译器在发现错误时给出警告或错误提示,有助于避免因为拼写错误或其他原因导致的潜在问题。

2)final可以用来修饰一个类或一个函数:

修饰一个类时,表示该类不可被继承。

修饰一个函数时,表示该函数不可被重写。

扩:不用final,如何让一个类不可被继承?

将构造函数私有化,并设置一个静态成员函数来调用其私有的构造函数。

六、 多态的原理是什么?虚表/虚函数表

1)父类中会有一个虚函数表指针类型的成员,创建父类对象后,该指针指向父类的虚函数表,该虚函数表保存的是父类虚函数指针;

2)子类继承父类后,会通过继承得到一个虚函数表指针类型的成员,创建子类对象后,该指针指向子类的虚函数表,该虚函数表保存的是子类虚函数指针。

同一个类的多个对象中的vfptr(虚函数表指针)指向的是同一个虚函数表。

下图可以验证上面的说法:

当test(p)执行时,pp是p对象的引用,pp看到的是这一部分(父类的虚函数表):

当test(s)执行时,pp是s对象的切片,pp看到的是这一部分(子类的虚函数表):

七、虚表保存在哪里?

验证猜测是在常量区。

八、坑题

正确答案是:B

九、多态分几种?哪几种?

多态分为静态多态和动态多态:

① 静态多态又称静态绑定,是指在程序编译期间就确定了程序的行为。(函数重载)

② 动态多态又称动态绑定,是指在程序运行期间才确定程序的行为。(继承、虚函数重写)

十、多继承+虚函数重写(多个父类的类会有几个虚表?)

 Derive对象是多大?有几个虚表指针?

20字节,两个虚表指针。

为什么Derive对象重写fun1后,两个虚表保存的函数指针不一样,调用的结果是同一个?

上面这段代码中,ptr123调用的都是同一个函数,也就是d对象的func1,而调用d对象的成员函数是要给它传d对象的this指针的,对于ptr1,由于它的地址与d对象的地址是刚好重合的,所以其虚函数表里保存的func1的地址就是真正的地址;ptr2则需要重新修正this指针的位置,让其指向d对象的起始地址。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/536428.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【vscode】在本地加载远端环境并开发

【vscode】在本地利用远程服务器显卡跑代码 写在最前面vscode:远程到本地1、安装ssh插件2、添加服务器连接配置3、连接服务器4. SSH配置5. 在ssh中安装python解释器 vscode基本操作 🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光…

得物 Zookeeper SLA 也可以 99.99% | 得物技术

一、背景 ZooKeeper(ZK)是一个诞生于2007年的分布式应用程序协调服务。尽管出于一些特殊的历史原因,许多业务场景仍然不得不依赖它。比如,Kafka、任务调度等。特别是在 Flink 混合部署 ETCD 解耦 时,业务方曾要求绝对…

双数据库的安装

双MySQL的安装 【0】前言 ​ 本地已经安装过mysql5.1版本,应项目需求需要安装mysql5.7版本; ​ 官方网站下载对应版本:https://downloads.mysql.com/archives/community/ 【1】压缩包下载完成后解压至本地磁盘 【2】进入根目录下bin文件夹…

Element-UI 自定义-下拉框选择年份

1.实现效果 场景表达&#xff1a; 默认展示当年的年份&#xff0c;默认展示前7年的年份 2.实现思路 创建一个新的Vue组件。 使用<select>元素和v-for指令来渲染年份下拉列表。 使用v-model来绑定选中的年份值。 3.实现代码展示 <template><div><el-…

数据结构复习指导之线性表(线性表的顺序表示)

文章目录 线性表的顺序表示 1.顺序表的定义 1.1知识总览 1.2顺序表 1.3静态分配 1.4动态分配 1.5顺序表的特点 1.6知识回顾与重要考点 线性表的顺序表示 1.顺序表的定义 1.1知识总览 1.2顺序表 线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性…

spring04:注解使用

spring04&#xff1a;注解使用 文章目录 spring04&#xff1a;注解使用前言&#xff1a;一、 Autowired Qualifier和 Resource 和 nullable1. Autowired 2. Resource &#xff1a;使用在类的属性上面&#xff08;和Autowired类似&#xff09;3. nullable 二、 Component 和 Re…

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE 请访问原文链接&#xff1a;JetBrains RubyMine 2024.1 (macOS, Linux, Windows) - 最智能的 Ruby 与 Rails IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org…

ELK日志

​​​​​​​

JavaGUI编程

目录 GUI概念 Swing概念 组件 容器组件 窗口&#xff08;JFrame&#xff09; 代码 运行 面板&#xff08;JPanel&#xff09; 代码 运行 布局管理器 FlowLayout 代码 运行 BorderLayout 代码 运行 GridLayout 代码 运行 常用组件 标签(JLabel) 代码 运…

Vue列表渲染

一、Vue列表渲染 1.用 v-for 把一个数组对应为一组元素 我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法&#xff0c;其中 items 是源数据数组&#xff0c;而 item 则是被迭代的数组元素的别名。 <ul id"exampl…

Agent调研--19类Agent框架对比

代理&#xff08;Agent&#xff09;指能自主感知环境并采取行动实现目标的智能体&#xff0c;即AI作为一个人或一个组织的代表&#xff0c;进行某种特定行为和交易&#xff0c;降低一个人或组织的工作复杂程度&#xff0c;减少工作量和沟通成本。 背景 目前&#xff0c;我们在探…

Qt 4.8中的ftp 功能在Qt 5.9.4 之前版本中的应用

很久以前也就是在Qt 4.8版本后&#xff0c; 如果想要用Qt ftp功能&#xff0c;是把Qt 4.8中的QFtp源码拉出来&#xff0c;编译、修改然后就能在Qt 其他版本使用。 但每一次升级Qt 版本&#xff0c;就要把Qt ftp 源码在相应的Qt 版本编译&#xff0c;修改。太麻烦了&#xff0c;…

C#下Httpclient post请求获取令牌

1.postman测试ok 2.C#代码 public static async Task<string> testGetToken(string URL, string param){string responseBody "eee";//using (var clientHandler new HttpClientHandler()){ var handler new HttpClientHandler();handler.ServerCertificat…

【JavaScript】对象 ② ( 对象使用 | 调用对象属性 | 调用对象方法 | 变量与属性区别 | 函数与方法区别 )

文章目录 一、对象使用1、使用字面量创建对象要点2、调用对象属性3、调用对象方法 二、变量与属性区别三、函数与方法区别 一、对象使用 1、使用字面量创建对象要点 使用字面量创建对象要点 : 在上一篇博客 【JavaScript】对象 ① ( 对象概念 | 对象使用场景 | 使用字面量创建对…

Android Studio开发学习(六)———TableLayout(表格布局)、FrameLayout(帧布局)

目录 前言 一、Tablelayout &#xff08;一&#xff09;Tablelayout的相关简介 &#xff08;二&#xff09;TableLayout使用方法 1. 当TableLayout下面写控件、则控件占据一行的大小。(自适应一行&#xff0c;不留空白) 2.多个组件占据一行&#xff0c;则配合TableRow实现…

Redis中的集群(六)

集群 ASK错误 在进行重新分片期间&#xff0c;源节点向目标节点迁移一个槽的过程中&#xff0c;可能会出现这样一种情况:属于被迁移槽的一部分键值对保存在源节点里面&#xff0c;而另一部分键值对则保存在目标节点里面。当客户端向源节点发送一个与数据库有关的命令&#xf…

【PHP程序设计(高阶版)】——PHP操作MySQL教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

Linux Ubantu安装配置教程

Ubuntu是一个基于Linux的开源操作系统&#xff0c;它遵循GNU通用公共许可证&#xff0c;用户可以自由使用、复制、分发和修改。它提供直观易用的桌面环境&#xff0c;适合新手和有经验用户。Ubuntu有强大的软件中心&#xff0c;支持多硬件架构&#xff0c;注重安全和稳定&#…

Hidl 学习总结 2

1、Android apk 调用Hidl处理 app添加对应的hidl jar包 2、MainActivity 添加如下代码 package com.example.test2;import androidx.appcompat.app.AppCompatActivity; import vendor.hardware.test.V1_0.ITest; import vendor.hardware.test.V1_0.ITestCmdCallback; import …

【精品PPT】智慧路灯大数据平台整体建设实施方案(免费下载)

1、知识星球下载&#xff1a; 如需下载完整PPTX可编辑源文件&#xff0c;请前往星球获取&#xff1a;https://t.zsxq.com/19QeHVt8y 2、免费领取步骤&#xff1a; 【1】关注公众号 方案驿站 【2】私信发送 【智慧路灯大数据平台】 【3】获取本方案PDF下载链接&#xff0c;直…