C++-------多态

news2024/11/26 7:50:17

一.如何实现多态

1.多态的两个条件: 

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

(2) 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写,重写必须返回值,函数名,参数类型相同,同时virtual只能修饰成员函数(这个和继承那个不同,继承的virtual解决的是菱形继承问题)。

class person {
public:
	virtual void buy()
	{
		cout << "全价" << endl;
	}

};
class student:public person{
public:
	void buy()//这里写不写virtual都可以,只要基类写了,规范是都写。
	{
		cout << "半价" << endl;
	}
};

void fun(person& p)
{
	p.buy();
}



2.多态的两个例外


(1)协变.

我们重写虚函数的时候,要保证返回值和参数,函数名相同,不过有个特列。允许返回值为父类或者子类的指针或者引用。它照样可以实现多态

(2)析构函数的重写


在继承中,析构函数由于多态的原因,会被编译器处理成同名函数,如果不加virtual,那么用基类的指针或者引用指向基类或者派生类,析构函数构成隐藏关系。会有内存泄漏的问题。

我们希望各自调用自己的析构,由于析构函数的函数名相同,参数为空,只要加基类析构函数加virtual就可以实现多态。


多态调用:通过父类的指针或者引用,来调用不同的虚函数.看对象不是看类型,指向什么对象就调用哪个对象的虚函数。它是在运行的时候来通过虚函数表里调用函数地址

普通调用:是在编译链接的时候就确定了函数的地址


二.常用的关键字:final,override

加强检查。

1. final:

修饰虚函数,表示该虚函数不能再被重写

2.override:

检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错,加强检查。

三.重写和重载和隐藏关系

重写是重定义(隐藏)的子集。

三.抽像类

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

抽象类要实现多态,必须子类实现对纯虚函数的重写。这也体现出,如果基类是抽象类,派生类必须要重写纯虚函数。

class animal {
public:
	virtual void eat() = 0;
};
class cat:public animal {
public:

	virtual void eat()
	{
		cout << "鱼" << endl;
}

};
class rabbit:public animal {
public:
	virtual void eat()
	{
		cout << "草" << endl;
	}

};

四.多态的原理

(1)单继承

多态调用是运行阶段通过虚函数表中的调用函数,实现多态。我们发现,person   p成员有个a,但是通过监视窗口看还有一个指针_vfptr.指向的是一个函数指针数组,这个是实现多态。

虚函数的重写也称虚函数的覆盖。为什么是父类指针和引用实现多态?父类中和派生类中构成多态,那么父类和子类成员会有个指针,都指向一个函数指针数组,数组中存的是虚函数的地址。

例如,子类(Derive)和父类(Base)各有一个虚函数表的指针,子类继承父类的时候会把父类的虚基表拷贝一份到自己的虚函数表中,如果父类某个虚函数被子类重写了,那么子类的虚函数表就把父类的虚函数地址覆盖 成子类的重写的,如果父类的指针或者引用指向子类。子类对象的地址前四个字节是虚函数表的地址,由于切割的原理这时看到是父类的部分,由与子类重写了func1,原来子类虚函数表中拷贝父类func1函数的地址已经子类重写的func1覆盖,子类虚函数表(地址003F7894)调用func1,这个时候调用的就是子类的func1,而不是父类的。

 对于多继承的情况。多继承派生类的未重写的虚函数放在第一个继承基类部分的虚函数表中,其中涉及到this指针的修正问题,对于菱形继承的多态比较复杂。

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

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

相关文章

Win10扩充C盘(把其他盘存储空间分给C盘)

C盘虽然没有安装任何软件&#xff0c;但无奈安装某些软件&#xff08;例如VS&#xff0c;QuarC等&#xff09;总会占用C盘容量&#xff0c;且C盘内存很小&#xff08;只有60G左右&#xff09;&#xff0c;看着D盘的三四十空闲内存&#xff0c;决定把D盘内存分给C盘30G&#xff…

uboot中内存DDR测试之mtest使用

相关代码路径: cmd/mem.c配置: make ARCHarm CROSS_COMPILEaarch64-linux-gnu- menuconfigCC cmd/mem.o cmd/mem.c: In function do_mem_mtest: cmd/mem.c:883:10: error: CONFIG_SYS_MEMTEST_START undeclared (first use in this function); did you mean CONFIG_SYS_…

Pbootcms留言“提交成功”的提示语怎么修改

我们在用到pbootcms建站时候&#xff0c;其中有个留言功能&#xff0c;提交成功后会提示&#xff1a;提交成功&#xff08;如下图所示&#xff09;&#xff0c;那么我们要修改这个提示语要怎么操作呢&#xff1f; 如果需要修改的话&#xff0c;直接找到文件/apps/home/control…

一投就中,收稿范围大,1个月内录用,国人发文最多,无风险预警

别人费心费力投个一年都不一定有结果&#xff0c;您直接坐上”直升飞机”&#xff0c;1个月录用。下面老毕分享1本超快录用EI期刊&#xff0c;工程电气方向的学者抓紧投稿。 抢占版面&#xff0c;下方【扫一扫】直接安排&#xff0c;1个月内录用&#x1f308; Journal of Elect…

骗2万人13亿的种菜游戏,幕后老板反手去当了榜一大哥…

这一届人民&#xff0c;可以说&#xff0c;对「种菜」式的田园生活&#xff0c;有一种执念。 或是格子间里日复一日的牢笼生活有些厌倦&#xff0c;也或是过快的城市化进程&#xff0c;让藏在基因里的「田园」属性&#xff0c;还能时不时的觉醒一下…… 除了诗与远方及前些年爆…

Pytest--安装与入门

pytest是一个能够简化成测试系统构建、方便测试规模扩展的框架&#xff0c;它让测试变得更具表现力和可读性–模版代码不再是必需的。只需要几分钟的时间&#xff0c;就可以对你的应用开始一个简单的单元测试或者复杂的功能测试。 1. 安装pytest pip install -U pytest检查版…

PD快充诱骗芯片工作原理,USB-C充电器出不来电压是什么原因?

一般使用Type-C接口的充电器基本上都是采用新的快充协议——PD快充协议&#xff0c;它不同于以前的USB-A的QC协议&#xff0c;这种协议&#xff0c;默认是没有快充电压输出的&#xff0c;VBUS和GND是0V。 所以&#xff0c;我们可以使用电阻的方式&#xff08;电流小&#xff09…

Steam新用户怎么参加夏促 Steam最新注册账号+下载客户端教程

steam夏促来了&#xff0c;这里给新玩家科普一下&#xff0c;steam就是一个游戏平台&#xff0c;里面的海量的各种游戏&#xff0c;而steam经常会有各种打折的活动&#xff0c;夏促就是其中之一&#xff0c;并且是其中规模最大的之一&#xff0c;涵盖游戏数量多&#xff0c;优惠…

【乐吾乐2D可视化组态编辑器】画布

5.1 设置画布属性 默认颜色&#xff1a;预先设置默认颜色&#xff0c;拖拽到画布的节点&#xff08;基础图形、文字、icon&#xff09;自动统一默认颜色。 画笔填充颜色&#xff1a;预先设置画笔填充颜色&#xff0c;拖拽到画布的节点&#xff08;基础图形&#xff09;自动统…

企业应该如果安全上网,软件防查盗版,企业防盗版

随着信息化的发展&#xff0c;企业日常办公越来越依赖互联网。终端以及普通PC终端在访问互联网过程中&#xff0c;会遇到各种各样不容忽视的风险&#xff0c;例如员工主动故意的数据泄漏&#xff0c;后台应用程序偷偷向外部发信息&#xff0c;木马间谍软件的外联&#xff0c;以…

java服务MultipartFile入参测试

项目中经常会涉及到文件的上传下载以及导入相关的功能&#xff0c;今天针对MultipartFile类型文档导入写一下如何测试。 文档导入接口完成&#xff0c;使用postman测试&#xff0c;使用POST方法&#xff0c;进入Body模块&#xff0c;选择form-data选项&#xff0c;key的框体右侧…

微信小程序根据蓝牙RSSI信号强度测试设备距离

背景 在做小程序连接蓝牙设备的时候&#xff0c;有需求表明在搜索到0.5米之内的设备时自动连接 问题&#xff1a; 蓝牙模组只提供了RSSI信号强度&#xff0c;那又该如何计算蓝牙设备距离小程序的距离呢&#xff1f; 解决方案 通过以下公式做大量测试&#xff1a;求 A、n 的平均…

npm创建一个空的vue3项目的方法或者pnpm创建vue3项目

1、前提我们已经安装了npm&#xff0c;或者pnpm 2、我们用npm来创建vue3项目 快速上手 | Vue.js 官网地址 这里我安装是的 node v18.20.3 以下是安装过程 &#xff1a; npm create vuelatest 根据自己的需要进行创建即可。 3、我们用pnpm来创建vite vue3项目 pnpm create …

SpringBoot项目中获取IP地址

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 OkHttp 是一个由 Square 开发的高效、现代的 HTTP 客户端库&#xff0c;用于 Android 和 Java 应用程序。它支持 HTTP/2 和 SPDY 等现代网络协议&#xff0c;…

Python28 十大机器学习算法之线性回归和逻辑回归

1.三类广义上的机器学习算法 监督学习。工作原理&#xff1a;该算法由一个目标/结果变量&#xff08;或因变量&#xff09;组成&#xff0c;该变量将从一组给定的预测变量&#xff08;自变量&#xff09;进行预测。使用这组变量&#xff0c;我们生成了一个将输入数据映射到所…

【python】pop()函数

python pop() &#xff0c;如何在Python的列表或数组中移除元素 使用 pop() 从列表中删除元素 pop() 语法概述 pop() 方法的语法如下&#xff1a; list_name.pop(index)list_name&#xff1a;列表变量名&#xff1b;内置的 pop() 方法仅需要一个可选参数&#xff1b;可选参…

async异步函数

文章目录 异步函数&#xff08;用 async 声明的函数&#xff09;异步函数的返回值async/await 的使用异步函数的异常处理总结 感谢铁子阅读&#xff0c;觉得有帮助的话点点关注点点赞&#xff0c;谢谢&#xff01; 异步函数&#xff08;用 async 声明的函数&#xff09; 异步函…

免疫防御和代谢控制十字路口的炎性小体

谷禾健康 人体的肠道粘膜内层形成物理屏障和免疫防御系统&#xff0c;以防止微生物入侵。当身体受到感染或细胞遭受损伤时&#xff0c;免疫系统会启动炎症反应来应对这些情况。炎症是对感染和组织损伤的一种急性反应&#xff0c;以限制对身体的伤害&#xff0c;这种反应是身体自…

Docker期末复习

云计算服务类型有: IaaS 基础设施及服务 PaaS 平台及服务 SaaS 软件及服务 服务类型辨析示例: IaaS 服务提供的云服务器软件到操作系统,具体应用软件自己安装,如腾讯云上申请的云服务器等;SaaS提供的服务就是具体的软件,例如微软的Office套件等。 云计算部署模式有: 私有云…

行业唯一!法大大斩获“数字可信服务——金牌奖”

近日&#xff0c;由BSI&#xff08;英国标准协会&#xff09;主办的第七届“万物互联 ∙ 智慧高峰”论坛暨第六届密码模块认证大会在上海成功举办&#xff0c;论坛上&#xff0c;法大大作为安全高效的电子合同智能签管平台&#xff0c;荣获BSI颁发的“数字可信服务——金牌奖”…