C++多态~~的两个特殊情况

目录

1.多态的概念

2.简单认识

(1)一个案例

(2)多态的两个满足条件

(3)虚函数的重写

(4)两个特殊情况


1.多态的概念

(1)多态就是多种形态;

(2)具体而言:就是不同的对象去完成相同的任务的时候,产生的效果是不一样的,产生了不同的形态;

2.简单认识

(1)一个案例

#include<iostream>
using namespace std;
class person
{
public:virtual void buyticket(){cout << "person成人票---全价" << endl;}
};
class student :public person
{
public:virtual void buyticket(){cout << "student学生票--半价" << endl;}
};
void func(person& p)
{p.buyticket();
}
int main()
{person p1;student st1;func(p1);func(st1);return 0;
}

我们这个就是拿的当代大学生乘坐动车和高铁可以获得折扣的例子演示的,我们定义了两个类,这两个类之间就是普通的继承关系,student继承person类,两个类里面都有一个虚函数,就是以virtual开头的函数,我们分别定义了两个对象,两个对象分别作为函数的参数传递进去,我们可以发现,当我们传递的参数是父类的对象的时候,我们会发现这个打印的结果就是成人票,我们传递的参数是子类对象的时候,这个打印的结果就是学生票,就是传递进去不同的参数,这个打印的结果就是不一样的,像这种我们把不同的对象,完成相同的任务(在这个里面就是去调用buyticket函数),出现不同的结果的现象,我们称之为多态;

(2)多态的两个满足条件

第一个就是虚函数的重写,第二个就是通过父类的指针或者是引用进行调用虚函数,这个指针或者是引用必须是父类的,因为这个如果是子类的话,他就是只能接受子类传递过来的对象,不能接受传递的父类的对象;

但是如果是父类的指针或者是引用的话,我们可以传递父类对象,也可以传递子类的对象,就算是传递的子类的对象,我们也是可以只把子类里面属于父类的成员函数和成员变量传递过去,这个就是复制兼容性规则,也就是我们常说的切片,在两个满足继承关系的情况下,这个是允许的;

(3)虚函数的重写

虚函数的重写也是需要满足三个条件的,都是针对这个父类和子类的函数的,父类和子类的虚函数要求满足函数的名字相同,函数的参数相同而且函数的返回值相同,这三个条件就是构成虚函数重写的条件,而虚函数的重写,又是构成多态的条件;

virtual只能进行修饰成员函数,否则(virtual修饰其他的非成员函数)就会报错;

(4)两个特殊情况

协变:虚函数的返回值可以不一样,但是要求必须是父类或者是子类的指针或者是引用;

下面就是这个特殊情况的举例,在这个函数的返回值是父类的引用或者是指针的时候,这个时候的函数的返回值虽然是不一样的,但是这个依然可以构成虚函数的重写;

class person
{
public:virtual person* buyticket(){cout << "person成人票---全价" << endl;return nullptr;}
};
class student :public person
{
public:virtual student* buyticket(){cout << "student学生票--半价" << endl;return nullptr;}
};

第二种特殊情况就是这个子类的虚函数可以不在这个函数的前面添加上virtual,这个其实是很重要的,为什么要这么进行设计,其实是和这个析构函数有一些关系的;

我们之前介绍过,因为多态的原因,这个在析构函数的执行会被进行特殊的处理,就是全部转化成为destructor(这个具体是什么我们后面还是会进行学习的);

下面我们给上面的这个案例的代码添加上析构函数,来解释一下为什么这个子类的虚函数的前面可以不用添加上virtual关键字;

这个运行结果也是没有问题的,因为我们执行完成之后进行对象的析构,p1是父类的对象就是调用父类的析构函数,s1是子类的对象就会先调用子类的析构函数,子类的析构函数执行完毕之后就会自动调用父类的析构函数(上一次我们在继承里面已经介绍过了,这个是在继承的前提下面默认进行的,而且是必须按照这个顺序,因为我们的子类继承了父类的成员变量或者是成员函数,我们先析构父类,如果这个子类里面使用就会造成野指针的问题,我们先析构子类,在析构父类的时候,父类是没有收到任何影响的,所以析构的顺序就是先子类后父类);

我们接下来换一种情况进行演示:

父类的指针可以指向父类的对象,也可以指向子类的对象,但是执行析构函数的时候,调用析构函数的时候是根据这个指针的类型调用的,所以两个析构都是调用的父类的构造函数,但是我们想要第二次调用子类的析构函数,这个时候我们就需要在这个析构函数的前面添加上virtual,就可以正确调用析构函数;

但是,如果我们忘记写这个virtual,我们只需要在这个父类析构函数前面加上virtual,我们在子类里面不添加virtual也可以完成这个正常的调用;

这个就是在我们忘记写子类的析构函数的情况下,只要我们把这个父类的析构函数前面加上virtual,我们这个子类里面不添加virtual也是可以正常调用的,这个就是上面的第二个特殊情况为这个情景开了一个绿灯,如果我们忘记写了,不会影响这个程序的执行;

但是,对于上面的这两个特殊情况,我们只需要了解即可,在我们平常去写代码的话,我们还是规范书写,减少这些不必要的麻烦;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL 29 计算用户的平均次日留存率题解

问题截图如下&#xff1a; SQL建表代码&#xff1a; drop table if exists user_profile; drop table if exists question_practice_detail; drop table if exists question_detail; CREATE TABLE user_profile ( id int NOT NULL, device_id int NOT NULL, gender varchar…

小白也能懂:逆向分析某网站加速乐Cookie参数流程详解

加速乐作为一种常见的反爬虫技术&#xff0c;在网络上已有大量详尽深入的教程可供参考。然而&#xff0c;对于那些初次接触的人来说&#xff0c;直接面对它可能仍会感到困惑。 声明 本文仅用于学习交流&#xff0c;学习探讨逆向知识&#xff0c;欢迎私信共享学习心得。如有侵权…

【区块链+基础设施】珠三角征信链 | FISCO BCOS应用案例

“珠三角征信链”是中国人民银行广州分行、中国人民银行深圳市中心支行按照中国人民银行总行工作部署&#xff0c;积 极贯彻珠三角一体化发展、粤港澳大湾区建设等国家战略而建设的跨区域征信一体化数据中心枢纽&#xff0c;以 FISCO BCOS 为底链构建应用平台&#xff0c;并由微…

springboot接口防抖【防重复提交】

什么是防抖 所谓防抖&#xff0c;一是防用户手抖&#xff0c;二是防网络抖动。在Web系统中&#xff0c;表单提交是一个非常常见的功能&#xff0c;如果不加控制&#xff0c;容易因为用户的误操作或网络延迟导致同一请求被发送多次&#xff0c;进而生成重复的数据记录。要针对用…

Docker 镜像导出和导入

docker 镜像导出 # 导出 docker 镜像到本地文件 docker save -o [输出文件名.tar] [镜像名称[:标签]] # 示例 docker save -o minio.tar minio/minio:latest-o 或 --output&#xff1a;指定导出文件的路径和名称[镜像名称[:标签]]&#xff1a;导出镜像名称以及可选的标签 dock…

【Python画图-驯化01】一文叫你搭建python画图最优环境配置

【Python画图-循环01】一文叫你搭建python画图最优环境配置 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注&#…

Windows/Linux/Mac 系统局域网服务发现协议及传输速度比较

简介 分析 / 验证对比常见局域网服务发现协议在 Windows/Linux/Mac 等不同系统下的支持和表现 在使用不同系统的智能硬件时&#xff0c;如常见的树莓派 / Openwrt 路由器 / Debian/Fedora/Windows/Mac 等系统是&#xff0c;系统间相互发现以及网络共享本应是系统的基础服务&a…

探秘 Django 专业之道

一、Django项目开发 1.web框架底层 1.1 网络通信 注意&#xff1a;局域网 个人一般写程序&#xff0c;想要让别人访问&#xff1a;阿里云、腾讯云。 去云平台租服务器&#xff08;含公网IP&#xff09;程序放在云服务器 先以局域网为例 我的电脑【服务端】 import sock…

Linux下SUID提权学习 - 从原理到使用

目录 1. 文件权限介绍1.1 suid权限1.2 sgid权限1.3 sticky权限 2. SUID权限3. 设置SUID权限4. SUID提权原理5. SUID提权步骤6. 常用指令的提权方法6.1 nmap6.2 find6.3 vim6.4 bash6.5 less6.6 more6.7 其他命令的提权方法 1. 文件权限介绍 linux的文件有普通权限和特殊权限&a…

计算机毕业设计Python深度学习美食推荐系统 美食可视化 美食数据分析大屏 美食爬虫 美团爬虫 机器学习 大数据毕业设计 Django Vue.js

Python美食推荐系统开题报告 一、项目背景与意义 随着互联网和移动技术的飞速发展&#xff0c;人们的生活方式发生了巨大变化&#xff0c;尤其是餐饮行业。在线美食平台如雨后春笋般涌现&#xff0c;为用户提供了丰富的美食选择。然而&#xff0c;如何在海量的餐饮信息中快速…

(1)Jupyter Notebook 下载及安装

目录 1. Jupyter Notebook是什么&#xff1f;2. Jupyter Notebook特征3. 应用3. 利用Google Colab安装Jupyter Notebook3.1 什么是 Colab&#xff1f;3.2 访问 Google Colab 1. Jupyter Notebook是什么&#xff1f; 百度百科: Jupyter Notebook&#xff08;此前被称为 IPython …

Unity Shader 软粒子

Unity Shader 软粒子 前言项目Shader连连看项目渲染管线设置 鸣谢 前言 当场景有点单调的时候&#xff0c;就需要一些粒子点缀&#xff0c;此时软粒子就可以发挥作用了。 使用软粒子与未使用软粒子对比图 项目 Shader连连看 这里插播一点&#xff0c;可以用Vertex Color与…

ARP 原理详解 二

只要确定了 IP 地址后&#xff0c;就能够向这个 IP 地址所在的主机发送数据报&#xff0c;这是我们所熟知的事情。 但是再往深了想&#xff0c;IP 地址只是标识网络层的地址&#xff0c;那么在网络层下方数据链路层是不是也有一个地址能够告诉对方主机自己的地址呢&#xff1f…

生产环境部署与协同开发-Docker(原创超全)

关闭防火墙 systemctl stop firewalld.service 关闭SELinux vim /etc/selinux/config 查看yum支持的包并安装docker引擎 yum listyum install -y docker 启动docker设置docker自启动测试docker是否安装成功&#xff1f; systemctl start dockersystemctl enable dockerdoc…

算法基础-----【动态规划】

动态规划(待完善) 动规五部曲分别为&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式&#xff08;状态转移公式&#xff09;dp数组如何初始化确定遍历顺序举例推导dp数组、 动态规划的核心就是递归剪枝&#xff08;存储键值&#xff0c;…

教师备课三要素是指什么内容

在教育的舞台上&#xff0c;教师的角色至关重要。他们不仅是知识的传递者&#xff0c;更是学生学习路上的引导者。那么&#xff0c;教师备课的三要素究竟是什么呢&#xff1f;这不仅是每个教师在教学过程中必须面对的问题&#xff0c;也是他们不断探索和实践的课题。 教师备课的…

如何通过TPM活动提升员工的设备管理能力?

在快节奏的现代职场中&#xff0c;设备管理能力已成为员工综合素质的重要一环。然而&#xff0c;如何有效提升这一能力&#xff0c;让员工在设备操作、维护和管理上更加得心应手呢&#xff1f;答案就隐藏在TPM&#xff08;Total Productive Maintenance&#xff0c;全面生产维护…

Python容器 之 列表--定义

1.什么是列表呢&#xff1f; 列表(list)是 Python 中使用最频繁的数据类型, 在其他语言中通常叫做数组, 专门用来存储一组数据 列表,list, 使用 [ ] 列表可以存放任意多个数据 列表中可以存放任意类型的数据 列表中数据之间 使用 逗号隔开 2.列表如何定义&#xff1f; &#…

【TB作品】atmega16 计算器,ATMEGA16单片机,Proteus仿真

实验报告&#xff1a;基于ATmega16单片机的简易计算器设计 1. 实验背景 计算器是日常生活和工作中不可或缺的工具&#xff0c;通过按键输入即可实现基本的四则运算。通过本实验&#xff0c;我们将利用ATmega16单片机、矩阵键盘和LCD1602显示屏&#xff0c;设计并实现一个简易…

2023软考中级《软件设计师》(备考冲刺版) | 数据库系统

目录 1.数据库的基本概念 1.1 数据库体系结构 1.2 三级模式结构 1.3 数据仓库 2.数据库设计过程 2.1 概念结构设计 2.1.1 概念设计过程 2.1.2 E-R图 2.2 逻辑结构设计 2.2.1 关系模式相关概念 2.2.2 E-R图转关系模式&#xff08;涉及下午题&#xff09; 2.2.3 关系…