c++的学习之路:22、多态(1)

news/2024/5/20 20:10:29/文章来源:https://blog.csdn.net/weixin_64257568/article/details/137612984

摘要

本章主要是说一些多态的开头。

目录

摘要

一、多态的概念

二、多态的定义及实现

2.1、多态的构成条件

2.2、虚函数

2.3、虚函数的重写

2.4、C++11 override 和 final 

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

三、思维导图


一、多态的概念

多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会
产生出不同的状态。

举个栗子:比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票,这个就很形象,虽然我一次没用过半价车票呜呜,但是这个就是一种多态的体现。

二、多态的定义及实现

2.1、多态的构成条件

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。那么在继承中要构成多态还有两个条件:

1. 必须通过基类的指针或者引用调用虚函数

2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

如下方代码就是多态构成实现的代码。

class Person
{
public:
    virtual void BuyTicket()
    {
        cout << "买票-全价" << endl;
    }
};
class Student :public Person
{
public:
    virtual void BuyTicket()
    {
        cout << "买票-半价" << endl;
    }
};

void Func(Person& People)
{
    People.BuyTicket();
}

int main()
{
    Person ZhangSan;
    Func(ZhangSan);
    Student LiSi;
    Func(LiSi);
}

2.2、虚函数

虚函数:即被virtual修饰的类成员函数称为虚函数,如下方代码。

class Person {
public:
virtual void BuyTicket() { cout << "买票-全价" << endl;}
};

2.3、虚函数的重写

虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的
返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。

注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用,如下方代码所示。

class Person
{
public:
    virtual void BuyTicket()
    {
        cout << "买票-全价" << endl;
    }
};
class Student :public Person
{
public:
    void BuyTicket()
    {
        cout << "买票-半价" << endl;
    }
};
 

虚函数重写的两个例外:

1. 协变(基类与派生类虚函数返回值类型不同)

派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变,如下方代码所示

class A{};
class B : public A {};
class Person {
public:
virtual A* f() {return new A;}
};
class Student : public Person {
public:
virtual B* f() {return new B;}
};

2. 析构函数的重写(基类与派生类析构函数的名字不同)

如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。 

注意: 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数,如下方代码所示。

class Person {
public:
    virtual ~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:
    virtual ~Student() { cout << "~Student()" << endl; }
};

int main()
{
    Person* p1 = new Person;
    Person* p2 = new Student;
        delete p1;
    delete p2;
    return 0;
}

2.4、C++11 override 和 final 

从上面可以看出,C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来debug会得不偿失,因此:C++11提供了override和final两个关键字,可以帮助用户检测是否重写。

1. final:修饰虚函数,表示该虚函数不能再被重写

2. override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

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

如下方图片就是三个概念的对比。

三、思维导图

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

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

相关文章

Harmony鸿蒙南向驱动开发-DAC

DAC&#xff08;Digital to Analog Converter&#xff09;是一种通过电流、电压或电荷的形式将数字信号转换为模拟信号的设备。 DAC模块支持数模转换的开发。它主要用于&#xff1a; 作为过程控制计算机系统的输出通道&#xff0c;与执行器相连&#xff0c;实现对生产过程的自…

牛客 2024春招冲刺题单 ONT98 牛牛猜节点【中等 斐波那契数列 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/6a3dfb5be4544381908529dc678ca6dd 思路 斐波那契数列参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规…

redis集群搭建过程遇到的坑

在上一篇博文中搭建好了redis集群&#xff0c;但是仍然存在很多问题 上一篇&#xff1a;k8s下搭建redis集群 1、springboot服务连接 集群配置好了&#xff0c;spring服务应该怎么连接呢&#xff1f;单点和集群的连接配置写法是不一样的 单点 spring:redis:host: ${BTC_RED…

水牛社软件:让网络小白少花冤枉钱,赚取第一桶金

大家好&#xff0c;我是木薯&#xff0c;水牛社赚钱软件的设计者&#xff0c;很感谢你的关注。我掘金互联网行业21年&#xff0c;操作了过去十余年来网上几乎所有的主流赚钱项目。我相信这个软件可以给你带来至少百倍的回报。 今年是软件上线第十个年头&#xff0c;去年底刚刚…

Tesseract 安装与配置及验证码识别

Tesseract 安装与配置 Tesseract 的使用&#xff0c;需要环境的支持&#xff0c;以实现简单的转换和训练。 1.环境 python版本&#xff1a;3.8.3 &#xff08;python2.7或3以上&#xff09; 操作系统&#xff1a;windows系统 2.Python安装 详见&#xff1a;Miniconda的…

创建型模式--4.抽象工厂模式【弗兰奇一家】

1. 奔向大海 在海贼世界中&#xff0c;位于水之都的弗兰奇一家是由铁人弗兰奇所领导的以拆船为职业的家族&#xff0c;当然了他们的逆向工程做的也很好&#xff0c;会拆船必然会造船。船是海贼们出海所必备的海上交通工具&#xff0c;它由很多的零件组成&#xff0c;从宏观上看…

Leetcode算法训练日记 | day19

一、最大二叉树 1.题目 Leetcode&#xff1a;第 654 题 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的…

每日Bug汇总--Day01

Bug汇总—Day01 一、项目运行出错 1、问题&#xff1a;运行苍穹外卖后端项目sky-take-out时&#xff0c;maven在install时报错 Maven resources compiler: Failed to copy D:\sky-take-out\sky-server\.....报错原因&#xff1a; 文件或者上级文件夹设置了只读用户没有修改…

【论文精读】| Geometric Multimodal Contrastive Representation Learning

本文并非逐句翻译&#xff0c;添加个人理解与疑惑&#xff0c;如有需要&#xff0c;请自行阅读原文。 Geometric Multimodal Contrastive Representation Learning 几何多模态对比表征学习 发表在 2022 ICML 数据集&#xff1a; 代码地址&#xff1a;GitHub - miguelsvasco/gmc…

ClickHouse 介绍

前言 一个通用系统意味着更广泛的适用性&#xff0c;但通用的另一种解释是平庸&#xff0c;因为它无法在所有场景内都做到极致。 ClickHouse 在没有像三驾马车这样的指导性论文的背景下&#xff0c;通过针对特定场景的极致优化&#xff0c;获得闪电般的查询性能。 ClickHous…

MySQL复制拓扑1

文章目录 主要内容一.安装MySQL服务器1.MySQL 安装程序和其它文件保存在下发的 mysql8-files.iso 镜像文件中&#xff0c;可以使用虚拟光驱来提取到 Linux 文件系统。代码如下&#xff08;示例&#xff09;: 2.将 MySQL8.0 程序解压到 /opt 目录&#xff0c;再创建到 MySQL 默认…

基于Java+SpringBoot+Vue文学名著分享系统(源码+文档+部署+讲解)

一.系统概述 随着世界经济信息化、全球化的到来和互联网的飞速发展&#xff0c;推动了各行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、动态的、交互友好的、高效的文学名著分享系统。当前的信息管理…

Spring Boot 切面的一种的测试方法,java中级开发面试

void afterReturnName() { Assertions.assertEquals(studentController.getNameById(123L).getName(), "测试姓名Yz");} } 但往往切面中的逻辑并非这么简单&#xff0c;在实际的测试中其实我们也完成没有必要关心在切面中到底发生了什么&#xff08;发生了什么应该在…

FreeRTOS任务切换学习

FreeRTOS任务切换学习 所谓任务切换&#xff0c;就是CPU寄存器的切换。假设当由任务A切换到任务B时&#xff0c;主要分为两步&#xff1a; 1&#xff1a;需暂停任务A的执行&#xff0c;并将此时任务A的寄存器保存到任务堆栈&#xff0c;这个过程叫做保存现场&#xff1b; 2&am…

【Redis系列】Redis安装与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

python 读取txt文件,文本拼接

# 定义你想要拼接的变量 variable_to_concatenate1 """ ,拼接文本,文本一, """ variable_to_concatenate2 """ ,文本二,拼接文本 """# 打开原始文件&#xff0c;并读取每一行 with open(example.txt, r, encodi…

HarmonyOS 开发-图片九宫格封装案例

介绍 本示例介绍使用(Flex) 组件实现图片在不同个数情况下的布局效果(默认布局和自定义布局)。该场景多用于社交类应用。 效果图预览 使用说明 默认布局情况下&#xff0c;传入图片资源imageSource&#xff08;类型为Resource[]&#xff09;&#xff0c;图片会按照个数进行相…

在Vue2里面加载AntvL7

1、代码块 <template><div ref"mapContainer" style"width: 800vh; height: 100vh; align-items: center; justify-content: center"></div> </template><script> export default {mounted() {this.initMap();},methods: {…

光伏电站运维管理平台功能分析

光伏电站的建设发展&#xff0c;不仅可以满足人们日益增长的用电需求&#xff0c;同时对于减少能源资源消耗也有着十分重要的作用。但是光伏电站因为区域跨度大&#xff0c;分布广泛等原因在建设发展中导致了人员管理困难、运维工作落实不到等问题&#xff0c;直接影响光伏电站…

SQL注入原理与信息获取及常规攻击思路靶场实现

SQL注入原理与信息获取及常规攻击思路靶场实现 很早的时候就写了&#xff0c;权当备份吧 Web程序三层架构 表示层 &#xff1a;与用户交互的界面 , 用于接收用户输入和显示处理后用户需要的数据 业务逻辑层 &#xff1a;表示层和数据库访问层之间的桥梁 , 实现业务逻辑 ,验证、…