C++进阶中多态的全部主要内容

news2024/11/13 22:34:53

今天小编和大家一起学习C++中多态的全部主要内容,希望今天大家和小编一起学习之后,会对多态有一个初步的了解和使用,好啦,话不多说,开始学习!~~~

一、多态的概念及满足条件

概念:指的就是不同的对象对于同一种情况会表现出不同的状态,以编程的角度来看,就是不同类型的对象调用相同的函数会产生不同的结果(输出不同)。举个例子,不同身份的人买票的价格不同,学生买票 ->学生票, 普通人 ->原价票, 军人买票 -> 优先买票。

那我们该如何用编程的角度实现上面的买票部分的代码呢,这就需要知到多态满足的条件之后来实现。

满足条件:1、被调用的函数必须是虚函数,并且在派生类里面必须对父类的虚函数进行重写。

                  2、使用过程中必须通过父类(基类)指针或者引用来调用虚函数。

在这里我们先说下虚函数的是什么:虚函数是被 virtual 所修饰的类成员函数,如下代码:

class Person
{
public:
	virtual void BuyTickts()
	{
		cout << "原价购买" << endl;
	}
private:

};

接下来我们说下对父类的虚函数进行重写:派生类中有一个和父类中完全相同的虚函数(即派生类的函数名,函数参数,函数返回值都相同),这就称为对父类的虚函数进行重写。

重点:虚函数的调用过程:1、父类的虚函数的函数名,函数参数,返回值部分

                                            2、子类虚函数的函数内容

以上就是多态的满足条件,为此再结合一幅图加深来理解:

接下来我们就实现一下买票的多态情况,代码如下:

class Person
{
public:
	// 虚函数满足三个条件 (virtual)
	// 函数返回值,函数名字,函数参数都要相同
	virtual void BuyTickts()
	{
		cout << "原价购买" << endl;
	}
private:

};

// 重点:虚函数的调用是 调用父类虚函数的返回值和函数名和函数参数,包括子类虚函数的函数内容
class Student : public Person
{
	virtual void BuyTickts()
	{
		cout << "半价购买" << endl;
	}
private:

};

class Solider : public Person
{
	virtual void BuyTickts()
	{
		cout << "优先购买" << endl;
	}
private:

};

void test(Person& s)
{
	s.BuyTickts();
}
// 测试在不同继承关系的类对象,去调用同一函数,产生了不同的行为
void test1()
{
	Student st;
	Solider so;
	test(st);
	test(so);
}

这样就可以做到调用谁的虚函数,就输出谁的虚函数的内容,也就是多态。

在这里虚函数还有两个特殊情况

        1、当重写虚函数的时候派生类函数的返回类型和基类的不相同,此时被称为协变,但是此时的返回值类型只能为基类的虚函数返回基类的指针或者引用,派生类返回值为派生类的指针或者引用。(了解内容)

        2、析构函数的重写,在这里虽然类中的析构函数名字不相同,并且析构函数前面没有加 virtual 按理说不满足虚函数重写的规则,但是编译器会默认将继承中的派生类和基类中的析构函数名字都处理为 destructor() 函数,并且无论析构函数是否加 virtual 都构成虚函数重写(相当于编译器默认加了 virtual) ,这样析构函数就构成多态,然后就可以做到指向谁就调用谁的析构函数,如下代码:

class Person 
{
public:
 virtual ~Person() {cout << "~Person()" << endl;}
};
class Student : public Person 
{
public:
 virtual ~Student() { cout << "~Student()" << endl; }
};
// 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。
int main()
{
 Person* p1 = new Person;
 Person* p2 = new Student;
 delete p1;      // 调用 Person 的析构函数
 delete p2;      // 调用 Student 的析构函数
 return 0;
}

二、C++11引入的两个关键字,重载,隐藏,复写的对比

1、final -> 虚函数不可再被复写

在不需要复写的虚函数后面加上 这个 final 的关键字,后面如果还对这个虚函数进行重写的话就会报错。具体如何使用如下:

class Car
{
public:
 virtual void Drive() final // 表示这个 Drive() 的虚函数不可以被复写
    {}
};
class Benz :public Car
{
public:
 virtual void Drive()       // 这里还对这个 Drive() 虚函数进行重写,就会报错
    {cout << "Benz-舒适" << endl;}
};

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

判断派生类中的虚函数是否是重写的基类中的某个虚函数,在派生类虚函数后面加上关键字 override 表示对派生类中的虚函数是否重写的基类中的虚函数进行检查,如果不是,就直接报错。具体使用方法如下:

class Car{
public:
 virtual void Drive()
    {}
};
class Benz :public Car {
public:
 virtual void Drive() override  // 检查 派生类虚函数 是否重写了基类某个虚函数
    {cout << "Benz-舒适" << endl;}
};

3、重载、隐藏、复写的对比图

三、抽象类

1、概念:包含纯虚函数的类称为抽象类,并且抽象类无法实例化出对象派生类继承抽象类之后,也无法实例化出对象,只有派生类对这个纯虚函数进行重写之后才可以实例化出对象

这里就又需要提到一个概念,也就是纯虚函数,语法很简单,直接看下面代码:

// 纯虚函数
// 语法:在基类的虚函数 后面 +  '= 0' 即可,这样就是纯虚函数
// 包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象
class Car
{
public:
	virtual void Drive() = 0; // 语法就是在基类虚函数后面加 = 0 即可,纯虚函数不能实例化处对象
};
class Benz :public Car
{
public:
	virtual void Drive()
	{
		cout << "Benz-舒适" << endl;
	}
};

这里 Car 的类里面包含纯虚函数,所以作为抽象类,它无法实例化出自己的对象,对于 Benz 这个类因为它重写了基类中的纯虚函数,所以它可以实例化出自己的对象。

注意:

四、多态的原理

1、虚函数和虚函数表的关系

对于存在虚函数的类而言,这个类中会多一个指针大小的内容,被称为虚函数表指针,具体怎么发现的请看一段代码及其运行结果:

继承父类后应该大小为8个字节,为什么多了4的字节,在32位机器上,由于 Derive 类中多了一个虚函数表指针,所以多了四个字节

那虚函数,虚函数表指针,虚函数表在类中的储存情况是什么样子的,这里以 Derive类 为例下面画图告诉大家:

好了,这就是今天多态的全部内容,希望大家看完之后都有所收获!~~~

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

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

相关文章

NC单链表的排序

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个节点…

九、OpenCVSharp 中的图像形态学操作

文章目录 简介一、腐蚀1. 腐蚀的原理和数学定义2. 结构元素的形状和大小选择3. 腐蚀操作的代码实现和效果展示二、膨胀1. 膨胀的概念和作用2. 与腐蚀的对比和组合使用(如开运算、闭运算)三、开运算1. 开运算的定义和用途(去除小的明亮区域)2. 开运算在去除噪声和分离物体方…

鸿蒙(API 12 Beta3版)【扩展屏投播开发指导】使用投播组件

通过本节开发指导&#xff0c;可在系统镜像投屏后&#xff0c;获取投屏设备信息&#xff0c;实现扩展屏模式的投播&#xff0c;实现双屏协作的能力。 运作机制 虚拟扩展屏 是在系统投屏启动过程中建立的&#xff0c;依据双端协商的投屏视频流的分辨率创建&#xff0c;支持1080…

OpenHarmony图像解码库—stb-image【GN编译】

简介 stb_image主要是C/C实现的图像解码库。 下载安装 直接在OpenHarmony-SIG仓中搜索stb-image并下载。 使用说明 以OpenHarmony 3.1 Beta的rk3568版本为例 库代码存放路径&#xff1a;./third_party/stb-image 修改添加依赖的编译脚本&#xff0c;路径&#xff1a;/devel…

哈希 | Java | (hot100) 力扣 49

我的想法&#xff1a;双重forhashset 方法一 由于互为字母异位词的两个字符串包含的字母相同&#xff0c;因此对两个字符串分别进行排序之后得到的字符串一定是相同的&#xff0c;故可以将排序之后的字符串作为哈希表的键。 力扣官方 values()方法返回一个包含HashMap中所有…

高性能日志系统 日志器模块

概述 作用&#xff1a;整合输出模块和格式化模块&#xff0c;创建日志器&#xff0c;通过该日志器对日志进行输出成员 格式化模块对象管理输出模块对象管理&#xff0c;数组管理&#xff08;日志器可能会向多个位置进行日志输出&#xff09;默认日志输出限制等级&#xff0c;只…

springboot智能城市交通管理系统-计算机毕业设计源码55174

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能…

React + React-tsparticles + Tsparticles完成炫酷的登录特效

效果(动态) npm i react-tsparticles2.12.2 npm i tsparticles2.12.0 注意:最好和上面的版本一样,不然会出现一个报错,具体如何解决的话去官网吧,上面的版本是没有问题的 代码块 总计6个代码块, options里面是相关粒子的配置 完整代码 import ./index.sass import { Form, Inp…

5个人共享一台高配工作站流程运行SW UG等软件大装配设计

如何实现5个人共享一台高配工作站流程运行SW UG等软件大装配设计&#xff1f; 一、前期准备 硬件准备&#xff1a; 选购一台高性能的服务器作为云主机&#xff0c;确保服务器具备足够的计算能力、内存和存储空间以支持多用户并发使用。云主机需要结合企业具体的使用情况和人数…

基于vue框架的哀牢犁耙会助农系统r4347(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,商品分类,商品信息 开题报告内容 基于Vue框架的哀牢犁耙会助农系统 开题报告 一、研究背景与意义 1.1 研究背景 随着科技的飞速发展&#xff0c;农业现代化已成为全球农业发展的重要趋势。传统的农业生产方式已难以满足现代农…

windows使用vscode和cmake编译报错error C2001: 常量中有换行符

报错图&#xff1a; 解决方法&#xff1a;修改通过编码保存的格式为GBK

微信小程序--23(条件渲染)

一、wx&#xff1a;if 1.作用 来判断是否需要渲染 2.语句 wx&#xff1a;if “{{condition}}”来判断是否需要渲染该代码块 wx&#xff1a;elifwx&#xff1a;else 用来添加else判断 3.演示 二、<block> wx&#xff1a;if 1.作用 <block>标签&#xff1a;…

4章7节:用R做数据重塑,数据去重和数据的匹配

在数据科学的分析流程中&#xff0c;数据重塑是一项非常重要的操作。数据的重塑通常指将数据从一种形式转换为另一种形式&#xff0c;以满足后续分析的需求。R语言提供了丰富的工具和函数来帮助用户高效地进行数据重塑操作。本文中&#xff0c;我们将深入探讨数据重塑的概念及其…

假如你正在备考六西格玛黑带,请看我的推文

众所周知&#xff0c;红宝书是备考六西格玛黑带的经典教材之一。那么&#xff0c;如何用红宝书高效备考六西格玛黑带呢&#xff1f;天行健六西格玛培训讲师总结如下&#xff1a; 1. 熟悉六西格玛概念&#xff1a;首先&#xff0c;你需要对六西格玛的基本概念有一个清晰的了解。…

智启万象|挖掘广告变现潜力,保障支付安全便捷

谷歌致力于为开发者提供 先进的广告变现与支付解决方案 一起回顾 2024 Google 开发者大会 了解如何利用谷歌最新工具和功能 提高变现收入&#xff0c;优化用户体验&#xff0c;保障交易安全 让变现更上一层楼 广告检查器是谷歌 AdMob 平台最新推出的高级测试工具&#xff0c;开…

mitmproxy 安装配置

下载地址&#xff1a; mitmproxy - an interactive HTTPS proxy 安装好之后&#xff0c;配置环境变量 我的电脑--右键---属性-----高级系统设置----环境变量-----path----编辑---将安装目录地址复制过来&#xff08;到 bin &#xff09; 查看版本&#xff1a;cmd----- mitmd…

【C++】——初识模板

目录 一、泛型编程 二、函数模板 2.1 定义 2.2 格式 2.3 生成原理 2.4 实例化 2.4.1 隐式实例化 2.4.2 显式实例化 2.5 匹配原则 三、类模板 3.1 定义格式 3.2 实例化 一、泛型编程 什么是泛型编程&#xff0c;大家可思考这个问题&#xff1a;swap函数大家都会实现&#x…

利用ZXing.Net Bindings for EmguCV识别条形码及绘制条形码边框17(C#)

上一篇博文&#xff1a;绘制条形码的效果不是很好&#xff1a;利用Emgucv绘制条形码边框16(C#)-CSDN博客 测试环境&#xff1a; win11 64位操作系统 visual studio 2022 ZXing.Net.Bindings.EmguCV 0.16.4 测试步骤如下&#xff1a; 1 新建.net framework 4.8的控制台项目…

正确利用AI工具,你的facebook广告效果将翻倍

如今投放facebook广告&#xff0c;你面临的对手已经不再是广告投手&#xff0c;而是AI&#xff0c;如果你的广告效果一直无法提升&#xff0c;不妨试着借助一下AI的力量&#xff0c;今天这篇文章就教你怎样才能让AI发挥它的最大价值&#xff0c;帮助我们的facebook广告效果提升…

STM32驱动SG90舵机完成控制

一、前言 SG90舵机的工作原理主要是基于PWM&#xff08;脉冲宽度调制&#xff09;信号来控制。 SG90舵机内部有一个基准电压&#xff0c;微处理器产生的PWM信号通过信号线进入舵机&#xff0c;产生直流偏置电压&#xff0c;与舵机内部的基准电压做比较获得电压差输出。电压差的…