简述何为多态

news2024/12/23 11:00:45

1.多态的概念

多态是什么?首先我们从概念讲起,简单来讲,多态就是多种形态,当你要去完成同一件事情的时候,不同的人去完成这件事情会有不同的结果.

比如在买票的时候,如果是成人去买票,则会买到成人票;如果是学生,则会买到学生票.

2.多态的实现以及构成条件

首先,多态的实现基础是继承,我们可以通过继承来实现多态.

具体的实现条件是什么?

1.调用的函数必须是虚函数,且虚函数必须要构成重写

2.必须要用基类或者派生类的指针或者引用去调用虚函数

那么这里就会有产生了两个问题.

1.什么是虚函数(父子类的虚函数)?

2.什么是重写?

1.虚函数

虚函数的写法很简单,直接在函数前面加一个virtual即可

这个在这里先简单介绍一下,后面会详细讲解

2.虚函数构成重写

那么什么是重写?

这里的虚函数构成重写是什么?

他跟函数重载不一样,这里的重写指的是,父类的子函数和基类的子函数,函数名,参数,返回值相同的情况下,则构成重写.

这种则是一个很经典的多态,里面的虚函数则构成了重写,可以看到,父类和子类的函数名,参数列表和返回值都相同.

但是重写的情况下,也会有两个例外.

例外1.协变

协变是派生类在重写基类虚函数时,与基类虚函数返回值类型不同.

注意,这里的返回值类型不同指的的父类或子类返回值是指针或者引用类型,如果返回类型一个是int,一个是void,则这个时候会编译报错,并不是重写.

也可以理解为当返回值是自定义类型的时候,他构成的则是重写,如果是一个内置类型,则会报错.

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.

3.override和final

final的作用是修饰虚函数,使得其不能再被重写.

class Person
{
public:
	virtual void Buy_Ticket() final
	{
		cout << "全票" << endl;
	}
};

override的作用是检查派生类的虚函数是否重写了基类的某个虚函数,如果没有则编译报错

class Car{
public:
 virtual void Drive(){}
};
class Benz :public Car {
public:
 virtual void Drive() override {cout << "Benz-舒适" << endl;}
};

3.抽象类

在虚函数的后面加个=0,则这个函数为纯虚函数.包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象,派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象

4.多态的原理

1.虚函数表指针

如果我们要讲清楚多态的原理,首先得引入一个指针,叫做虚函数表指针,简称虚表指针

虚表指针是什么?他存在于哪个地方?我们可以用接下来的这个代码来进行测试

class Base
{
	virtual void Fun1()
	{
		cout << "Fun1()" << endl;
	}
	virtual void Fun2()
	{
		cout << "Fun2()" << endl;
	}
	void Fun3()
	{
		cout << "Fun3()" << endl;
	}
};

int main()
{
	Base b;
	return 0;
}

我们在这里首先用Base来创建了一个b对象,通过调试我们可以看到,这个对象里面包含着一个vfptr

这个_vfptr就是所谓的虚表指针,这个指针里面存放着Fun1的地址和Fun2的地址

下面这个则是_vfptr的地址

当前的环境是x64,所以可以看出来这个的大小是8个字节.

我们也可以观察到,里面是没有Fun3()这个函数指针的,也就是说,只有在函数面前加了关键字virtual, 虚表指针才能指向这个函数的指针.

我们也得出一个结论,如果有虚函数,则就一定会有虚表指针.

2.多态怎么去实现调用的

要明白多态是怎么实现调用谁就是谁的,我们首先来看这段代码

class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-半价" << endl; }
};
void Func(Person& p)
{
	p.BuyTicket();
}
int main()
{
	Person Mike;
	Func(Mike);
	Student Johnson;
	Func(Johnson);
	return 0;
}

首先来简单看一下这段代码,我们用Person 来创建了Mike这个对象,然后用Student 来创建Johnson这个对象,那么我们现在看看Mike对象的内存

Mike :

Johnson:

这里为什么会有一个小地址跟Mike对象是一样的呢?这是因为Mike是基类,Johnson是继承Mike类的,而继承是通过切片的方式来继承,所以会有一小段地址是一样的.

然后我们再来看这个虚表指针的指向,可以发现,Mike指向的是父类,在父类里面找到了父类的虚函数进行调用;而Johnson则是指向了子类,在子类里面找到了子类重写的虚函数进行调用,最终达到了指向谁调用谁的目的.

我们由此可以得出一个结论,就是说,如果满足多态条件,就会去指向对象的虚表中找到对应的虚函数进行调用.

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

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

相关文章

【Flutter、Web——前端个人总结】分享从业经历经验、自我规范准则,纯干货

前言 hi&#xff0c;正式接触web前端已经经过了两年的时间&#xff0c;从大学的java后端转型到web前端&#xff0c;再到后续转战Flutter&#xff0c;逐渐对前端有了一些心得体会&#xff0c;其实在当下前端的呈现形式一直在变化&#xff0c;无论你是用原生、还是web还是混编的…

Django 1.2标准日志模块出现奇怪行为时的解决方案

在 Django 1.2 中&#xff0c;标准日志模块有时会出现意想不到的行为&#xff0c;例如日志消息未按预期记录、日志级别未正确应用或日志格式错乱等。这些问题可能源于日志配置不当、日志模块被多次初始化、或日志模块被其他包覆盖等原因。下面是一些常见问题的排查方法和解决方…

力扣21~25题

21题&#xff08;简单&#xff09;&#xff1a; 分析&#xff1a; 按要求照做就好了&#xff0c;这种链表基本操作适合用c写&#xff0c;python用起来真的很奇怪 python代码&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, v…

二、MySQL的数据目录

文章目录 1. MySQL8的主要目录结构1.1 数据库文件的存放路径1.2 相关命令目录1.3 配置文件目录 2. 数据库和文件系统的关系2.1 查看默认数据库2.2 数据库在文件系统中的表示2.3 表在文件系统中的表示2.3.1 InnoDB存储引擎模式2.3.2 MyISAM存储引擎模式 2.4 小结 1. MySQL8的主要…

宝塔docker中如何修改应用配置文件参数

今天在宝塔docker安装了kkfileview&#xff0c;相修改应用里的application.properties&#xff0c;却找不到在哪&#xff0c;如何修改&#xff1f; 下面教大家应用找文件修改。 docker安装好对应容器后&#xff0c;是这样 在这里是找不到对应修改的地方&#xff0c;其实docker…

Linux WIFI 驱动实验

直接参考【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81 本文仅作为个人笔记使用&#xff0c;方便进一步记录自己的实践总结。 WIFI 的使用已经很常见了&#xff0c;手机、平板、汽车等等&#xff0c;虽然可以使用有线网络&#xff0c;但是有时候很多设备存在布线困难的情况&…

Windows10的MinGW安装和VS Code配置C/C++编译环境

1. MinGW下载安装 首先需要说明的是VS Code是一个编辑器&#xff0c;而不是编译器。‌ 编辑器和编译器是有很明显的区别 1.1 编辑器和编译器区别 编辑器‌是一种用于编写和编辑文本的应用软件&#xff0c;主要用于编写程序的源代码。编辑器提供基本的文本编辑功能&#xff0c;…

面试题:Redis(三)

1. 面试题 背景 问题&#xff0c;上面业务逻辑你用java代码如何写&#xff1f; 2. 缓存双写一致性谈谈你的理解&#xff1f; 3. 双检加锁策略 多个线程同时去查询数据库的这条数据&#xff0c;那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。 其他的线程走到这…

内核编译 设备驱动 驱动程序

内核编译 一、内核编译的步骤 编译步骤&#xff1a; (linux 内核源码的顶层目录下操作 ) 1. 拷贝默认配置到 .config cp config_mini2440_td35 .config 2. make menuconfig 内核配置 make menuconfig 3. make uImage make u…

docker-compose无法切换用户

问题描述 jupyter:image: flink:1.19-pyprivileged: trueuser: rootports:- "9999:8888"volumes:- /data/docker_data/jupyter:/workcommand: sh -c "cd / && jupyter notebook --ip 0.0.0.0 --port 8888 --allow-root --NotebookApp.passwordsha1:658…

循环神经网络-LSTM网络

文章目录 前言一、LSTM网络简介二、LSTM的门结构1.遗忘门2.输入门3.输出门 三、总结 前言 循环神经网络&#xff08;Recurrent Neural Networks&#xff0c;RNN&#xff09;是一种特殊的神经网络&#xff0c;具有能够处理序列数据的能力&#xff0c;然而&#xff0c;RNN在处理…

团员申请书怎么写?这里归纳了一些模板

团员申请书怎么写&#xff1f;随着社会的快速发展和时代的进步&#xff0c;越来越多的青年人意识到加入团组织的重要性。作为新时代的青年&#xff0c;我们应当积极响应国家的号召&#xff0c;参与到团组织的建设中来。而想要成为共青团员&#xff0c;首先需要撰写一份规范的团…

新手一次过软考高级(系统架构设计师)秘笈,请收藏!

软考系统架构设计师是高级科目之一&#xff0c;也是比较有难度的科目&#xff0c;但是只要你把该掌握的知识掌握熟练&#xff0c;技能水平达到要求&#xff0c;那还是考可以拿下证书的。 系统架构设计师适合人群&#xff1a;适合熟悉开发过程与方法、数据库、信息安全的技术人员…

NLP: SBERT介绍及sentence-transformers库的使用

1. Sentence-BERT Sentence-BERT(简写SBERT)模型是BERT模型最有趣的变体之一&#xff0c;通过扩展预训练的BERT模型来获得固定长度的句子特征&#xff0c;主要用于句子对分类、计算两个句子之间的相似度任务。 1.1 计算句子特征 SBERT模型同样是将句子标记送入预训练的BERT模型…

OmniH2O——通用灵巧且可全身远程操作并学习的人形机器人(其前身H2O是HumanPlus的重要参考)

前言 由于我司一直在针对各个工厂、公司、客户特定的业务场景&#xff0c;做解决方案或定制开发&#xff0c;所以针对每一个场景&#xff0c;我们都会反复考虑用什么样的机器人做定制开发 于此&#xff0c;便不可避免的追踪国内外最前沿的机器人技术进展&#xff0c;本来准备…

数据库管理-第249期 23ai:全球分布式数据库-请求路由与查询过程(20241008)

数据库管理249期 2024-10-08 数据库管理-第249期 23ai&#xff1a;全球分布式数据库-请求路由与查询过程&#xff08;20241008&#xff09;1 客户端应用请求路由1.1 分片键1.2 Oracle连接驱动 2 查询过程和查询协调器2.1 指定一致性级别2.2 高可用与性能 总结 数据库管理-第249…

拍立淘API接口以图搜商品列表功能实现技术分享item_search_img|返回商品列表商品id商品价格url

开发背景 在电商平台的快速发展中&#xff0c;用户对于商品搜索的效率和准确性提出了越来越高的要求。传统的基于关键词的搜索方式&#xff0c;虽然在一定程度上满足了用户的需求&#xff0c;但在面对复杂的商品信息和多样化的用户搜索意图时&#xff0c;仍存在诸多局限性。为…

PyTorch搭建GNN(GCN、GraphSAGE和GAT)实现多节点、单节点内多变量输入多变量输出时空预测

目录 I. 前言II. 数据集说明III. 模型3.1 GCN3.2 GraphSAGE3.3 GAT IV. 训练与测试V. 实验结果 I. 前言 前面已经写了很多关于时间序列预测的文章&#xff1a; 深入理解PyTorch中LSTM的输入和输出&#xff08;从input输入到Linear输出&#xff09;PyTorch搭建LSTM实现时间序列…

IO相关,标准输入输出及错误提示

一、IO简介 1.1 IO的过程 操作系统的概念&#xff1a;向下统筹控制硬件&#xff0c;向上为用户提供接口。 操作系统的组成 内核 外壳&#xff08;shell&#xff09; linux的五大功能&#xff1a;进程管理、内存管理、文件管理、设备管理、网络管理。 最早接触的IO&#xf…

01背包,CF 1974E - Money Buys Happiness

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1974E - Money Buys Happiness 二、解题报告 1、思路分析 问我们能够到达…