C++中的多态,以及多态的实现、以及实现多态的两个特例。

news2024/12/25 12:19:39

一、 多态是什么?

        通俗点说,就是多种形态。具体点就是不同对象完成某种事情,会产生不一样的状态。

        举个例子:就好比:买票的时候,普通人、学生、军人等等,他们买票有不同的结果,普通人全价票,学生享受学生价的票,军人有优先购票以及军人的票价。

二、 多态的实现

        1、构成多态有两个条件:

                (1)必须是基类的指针或者基类的引用调用虚函数。

                (2)被调用的函数必须是虚函数,并且派生类必须对基类的虚函数进行重写。(有两个特殊)

简单点说就是:1. 虚函数重写        2. 父类指针或者引用去调用虚函数

        2、什么是虚函数?

                虚函数就是在成员函数前面加 virtual 修饰

         3、虚函数重写/覆盖条件:

                (1)虚函数 + 三同(函数名,参数,返回值)

                (2)不符合重写,就是隐藏关系

注意:(两个特殊)

        (1)子类虚函数不加 virtual 依旧构成重写(最好加上)

        (2)重写的协变。返回值可以不同,要求必须是父子关系的指针或者引用

下面用代码看一下,如下:

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

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

class Soldier : public Person
{
public:
	virtual void BuyTicket() { cout << "买票优先" << endl; }
};

//void Func(Person p) // 不是父类的指针或者引用就不是多态
void Func(Person& p)
{
	p.BuyTicket();
}

int main()
{
	Person p;
	Student st;
	Soldier so;

	Func(p);
	Func(st);
	Func(so);

	return 0;
}

运行之后,结果如下:

 

上面运行结果可以看出来,不同的对象传给父类的引用,所调的函数是不一样的。

4 . 下面我打破多态的两个条件看一下。如下:

        (1)打破父类的指针或者引用

                我将引用改为普通对象调用,看一下结果如何,如下:

void Func(Person p) // 不是父类的指针或者引用就不是多态
//void Func(Person& p)
{
	p.BuyTicket();
}

运行结果如下:

修改之后,结果都掉的是 Person 的成员函数,为什么?因为修改之后就是普通调用了(具体细节我在下一篇文章细讲)

        (2)打破重写的条件(重写:虚函数 + 三同)

                ① 我将父类中的虚函数去掉,如下:

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

运行结果如下:

也是如此,结果都是调用父类的方法。

                 ② 去掉三同中的函数名相同,这里我将三个函数名都改为不一样,如下:(如果改一个,那么其他两个还是相同,结果是各自的成员函数打印出来的结果)

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

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

class Soldier : public Person
{
public:
	virtual void BuyTi() { cout << "买票优先" << endl; }
};

运行结果如下:

5. 下面解释一下两个特例

        (1)子类虚函数不加 virtual 依旧构成重写(最好加上)

        (2)重写的协变。返回值可以不同,要求必须是父子关系的指针或者引用

先解释(1),如下:

我将 student、soldier 的成员函数的 virtual 去掉了,那么这两个成员函数就不是虚函数了吧?

那么结果怎么样?如下:

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

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

class Soldier : public Person
{
public:
	//virtual void BuyTicket() { cout << "买票优先" << endl; }
	void BuyTicket() { cout << "买票优先" << endl; }
};

运行结果如下:

运行结果还是各自的方法,为什么?

        因为子类继承父类之后,将父类的虚函数继承下来了,重写了父类的方法,简单点说就是,子类继承之后,子类中也有一样的虚函数,但是虚函数的实现依然是子类的。

最后解释(2),如下:

 虽然返回值可以同,但是必须是父子关系的指针或者引用,我这里就用引用解释一下,如下:

class Person {
public:
	virtual Person& BuyTicket()
	{
		cout << "买票全价" << endl;
		return *this;
	}
};

class Student : public Person
{
public:
	virtual Student& BuyTicket()
	{ 
		cout << "买票半价" << endl; 
		return *this;
	}
};

class Soldier : public Person
{
public:
	virtual Soldier& BuyTicket() 
	{ 
		cout << "买票优先" << endl; 
		return *this;  
	}
};

运行结果如下: 

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

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

相关文章

从零搭建完整python自动化测试框架(UI自动化和接口自动化 )

目录 一、总体框架 二、PO模式、DDT数据驱动、关键字驱动 三、框架技术选择 四、框架运行结果 五、各用例对应的定义方式&#xff08;PO/DDT&#xff09; 六、API接口定义方式 七、测试执行结果 从零开始搭建项目 一、开发环境搭建 二、新建项目 三、基础功能实现 …

前两天面了个腾讯28K来的,让我见识到了测试界的天花板

马上又是一年毕业季了&#xff0c;那么去年那一批毕业的应届生怎么样了&#xff1f; 2022年堪称大学生就业最难的一年&#xff0c;应届毕业生人数是1076万。失业率超50%&#xff01; 但是我观察到一个数据&#xff0c;那就是已经就业的毕业生中&#xff0c;计算机通信等行业最…

数据结构(C语言):一元多项式的操作(链表实现)

一、题目 一元多项式的操作 设有两个一元多项式&#xff1a; p(x)p0p1xp2x2pnxn q(x)q0q1xq2x2qmxm 多项式项的系数为实数&#xff0c;指数为整数&#xff0c;设计实现一元多项式操作的程序&#xff1a; ① 多项式链表建立&#xff1a;以&#xff08;系数&#xff0c;指数…

国内最佳的客服系统Tidio替代品是什么?

许多做跨境电商的企业都知道&#xff0c;Tidio是一款不错的为电子商务量身定制的全渠道客服系统支持工具&#xff0c;但还有其他同样不错的选择。 当前许多同类型产品以迎合欧美客户居多&#xff0c;中国用户使用不惯&#xff1b;免费版体验门槛高&#xff1b;只支持海外支付方…

【链路追踪】「Go语言」OpenTelemetry实现[gin, gRPC, log, gorm, redis]的集成

文章目录 一、OpenTelemetry的前世今生OpenTracingOpenCensus大一统 二、OpenTelemetry快速体验go快速体验OpenTelemetry系统架构尾部采样 三、通过http完成span传输函数中传递span的context 四、自定义inject和extract源码五、gRPC集成自用框架集成&#xff08;无视即可&#…

最强chrome、edge的广告拦截插件

最强chrome、edge的广告拦截插件 对于浏览器的广告是非常烦人的&#xff0c;尤其是使用百度搜索引擎时&#xff0c;总会在右侧出现百度热搜这样的东西&#xff0c;有时不经意间就会被某些热搜吸引。本来想搜索一些内容&#xff0c;结果被热搜等耗费了大量时间。 有很多人推荐…

pytorch基础语法学习:数据预处理transforms模块

来源&#xff1a;投稿 作者&#xff1a;阿克西 编辑&#xff1a;学姐 建议搭配视频食用 视频链接&#xff1a;https://ai.deepshare.net/detail/p_5df0ad9a09d37_qYqVmt85/6 系列其他文章传送门&#xff1a; pytorch基础语法学习&#xff1a;数据读取机制Dataloader与Datase…

3D点云数据转为俯瞰图Python实现代码

我主要是参考了英文博客来撰写本篇文章&#xff0c;仅作为个人学习笔记参考使用。 文章目录 一、点云数据二、图像与点云坐标三、创建点云数据的鸟瞰视图3.1 鸟瞰图的相关坐标轴3.2 限制点云数据范围3.3 将点位置映射到像素位置3.4 切换到新的零点3.5 像素值3.6 创建图像矩阵3.…

IOS最新版开通GPT-PLUS方法

前提&#xff0c;美国IP魔法 不多说了 1.拥有一个美区apple id账号 可以买&#xff0c;也可以自己申请 自己申请就打开魔法到apple官网注册&#xff0c;用gmail邮箱&#xff0c;然后地址用美国地址生成器&#xff0c;记得选免税州 2.充值礼品卡 支付宝可以充值礼品卡&…

大模型总是「胡说八道」怎么办?手把手教你如何应对!

随着 ChatGPT 的出现&#xff0c;「AI 幻觉」一词被频繁提及。那么&#xff0c;什么是 AI 幻觉&#xff1f;简单来说&#xff0c;就是大模型在一本正经地胡说八道。 不止 ChatGPT&#xff0c;其他大语言模型也经常如此&#xff0c;究其根本是大语言模型在训练的过程中存在数据偏…

驱动开发-----io模型总结(2023-5-23)

1.非阻塞模型 在我们使用open函数时&#xff0c;将打开的驱动设置为O_NONBLOCK时&#xff0c;当我们用read函数去读取硬件数据时&#xff0c;无论硬件是否有数据&#xff0c;都会往下执行&#xff0c;不会被阻塞在这里 2.阻塞模型 在我们使用open函数时&#xff0c;没有设置…

C++学习之路-变量和基本内置类型

变量和基本内置类型 一、基本内置类型1.1 算数类型1.2 带符号类型和无符号类型1.3 类型转换含有无符号类型的表达式 1.4 字面值常量整形和浮点型字面值字符和字符串字面值转义序列指定字面值的类型 二、变量2.1 变量的定义初始化列表初始化默认初始化 2.2 变量声明和定义的关系…

斐波那契数列数列相关简化1

斐波那契数列问题介绍&#xff1a; 斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;因数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为“兔子数列”&#xf…

包管理工具详解npm、yarn、cnpm、npx、pnpm

目录&#xff1a; 1 npm包管理工具 2 package配置文件 3 npm install原理 4 yarn、cnpm、npx 5 发布自己的开发包 6 pnpm使用和原理 当我们使用npm install xxxx 的时候会添加一个node_module和2个json文件&#xff1a; package.json是配置信息文件&#xff0c;  这个配…

Go完整即时通讯项目及Go的生态介绍

Go完整即时通讯项目 项目架构&#xff1a; 1 编写基本服务端-Server server.go package mainimport ("fmt""net" )// 定义服务端 type Server struct {ip stringport int }// 创建一个Server func NewServer(ip string, port int) *Server {return …

Jenkins + docker-compose 在 Centos 上搭建部署

一、前期准备 1. 检查 CentOS上 是否安装 docker 可以使用以下命令&#xff1a; sudo docker version 如果已经安装了Docker&#xff0c;它将显示有关Docker版本和构建信息的输出。如果未安装Docker&#xff0c;将收到有关命令未找到的错误消息。 2. 检查是否安装 docker-…

cookie-机制

目录 一、基础概念 二、cookie的处理方式 一、基础概念 1、cookie是存储在客户端的一组键值对 2、web中cookie的典型应用&#xff1a;免密登陆 3、cookie和爬虫之间的关联 有时&#xff0c;对一张页面进行请求的时候&#xff0c;如果请求的过程中不携带cookie的话&#xf…

Openai+Coursera: ChatGPT Prompt Engineering(四)

想和大家分享一下最近学习的Coursera和openai联合打造ChatGPT Prompt Engineering在线课程.以下是我写的关于该课程的前两篇博客&#xff1a; ChatGPT Prompt Engineering(一)ChatGPT Prompt Engineering(二)ChatGPT Prompt Engineering(三) 今天我们来学习第三部分内容&…

Java on Azure Tooling 4月更新|路线图更新及 Azure Toolkit for IntelliJ 增强

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Java on Azure 工具产品的4月更新。让我们首先来谈谈我们对未来几个月的 Java on Azure 开发工具的投资。在这次更新中&#xff0c;我们…

js - 闭包

1、闭包的概念 闭包&#xff1a;函数嵌套函数&#xff0c;内层函数访问了外层函数的局部变量。 // 闭包 function func1() {let a 9;let b 8;function func2() {console.log("a", a); // a 9}func2(); } func1(); 分析&#xff1a; 需要访问的变量会被放到闭包…