【C++】三大特性之多态

news2024/11/16 20:38:39

1 定义及实现

1.1 概念

多态是C++三大特性之一。通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如学生买票半价这个行为,Student继承了Person。Person对象买票全价,Student对象买票半价。对于买票这个行为,产生了不同的结果。

virtual关键字只在声明时加上,在类外实现时不能加

静态成员函数与具体对象无关,属于整个类,核心关键是没有隐藏的this指针,此时没有this无法拿到虚表,就无法实现多态,因此不能设置为虚函数

1.2 多态的构成条件

由上我们可以知道,多态是基于继承关系的。而想要在继承中要构成多态还有两个条件:

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

父子类中两个虚函数,三同(函数名、参数、返回值)
重写和隐藏比较类似,隐藏是函数名相同就构成隐藏,而重写的条件更加苛刻,可以看做是隐藏的子集再子集

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

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

普通调用 看指针、引用、对象的类型
多态调用 看指针、引用指向的对象

什么是虚函数呢?其实,被virtual修饰的类成员函数称为虚函数

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

1.3 虚函数重写的两个例外

  1. 协变(基类与派生类虚函数返回值类型不同)
    虚函数返回值可以不同,但是必须是父子类关系的指针或引用,即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用
    在这里插入图片描述

编译器进行了强制检查,否则应该构成隐藏

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

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

在这里插入图片描述

☆☆☆重写是实现重写

对虚函数进行重写时,用的是父类中的声明,子类中只是对函数体内容的实现进行重写,最终的函数其实是父类声明和子类实现的组合体。


2 C++11 override 和 final

  1. final:修饰虚函数,表示该虚函数不能被重写 #final
// 以下编译不通过
class Car
{
public:
	virtual void Drive() final {}
};
class Benz :public Car
{
public:
	virtual void Drive() {cout << "Benz-舒适" << endl;}
};
  1. override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。
    在这里插入图片描述

3 抽象类

3.1 概念

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

3.2 接口继承与实现继承

普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数。


4 多态的原理

4.1 虚函数表

实现多态的原理是虚函数表。
一个类存在虚函数,那么编译器就会为这个类生成一个虚表,在虚表里存放的是这个类所有虚函数的地址。当生成类对象的时候,编译器会自动的将类对象的前四个字节设置为虚表的地址,而这四个字节就可以看作是一个指向虚表的指针。虚表里依次存放的是虚函数的地址,每个虚函数的地址占4个字节。
![[Pasted image 20240310190553.png]]
虚函数表(本质是函数指针数组)

_vfptr 虚函数表指针,简称虚表指针

虚函数的重写也叫覆盖
重写是语法层的概念
覆盖是原理层的概念

![[Pasted image 20240310191318.png]]

解释:子类先把父类的虚表拷贝一份,如果发现有重写,就在子类虚表中将被重写的函数指针覆盖掉

![[Pasted image 20240310192430.png]]

实际就是编译器也不知道指向的是谁,只需要到指向的对象中去找虚函数表调用,本质从汇编的角度看到的就是父类,只是看该父类是原生父类还是子类切片出的父类

多态调用的函数和普通调用的函数其实是一个函数,只是调用的方式不一样
![[Pasted image 20240310193139.png]]![[Pasted image 20240312204820.png]]

子类新增虚函数,监视窗口看不到,但是内存窗口可以看到
![[Pasted image 20240312205400.png]]

虚函数表存在哪里呢?

虚表存放在常量区
一个类存在虚函数,那么编译器就会为这个类生成一个虚表,在虚表里存放的是这个类所有虚函数的地址。当生成类对象的时候,编译器会自动的将类对象的前四个字节设置为虚表的地址,而这四个字节就可以看作是一个指向虚表的指针。虚表里依次存放的是虚函数的地址,每个虚函数的地址占4个字节。
在这里插入图片描述

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

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

相关文章

基于vue实现bilibili网页

学校要求的实验设计,基于vue实现bilibili网页版,可实现以下功能 (1)基本的悬浮动画和页面渲染 (2)可实现登录和未登录的页面变化 (3)在登录页面的,实现密码判断,或者短信验证方式的倒数功能 (4)实现轮播图 (5)实现预览视频(GIF) (6)页面下拉到一定高度出现top栏以及右下角的返回…

CentOS 7 编译安装 Nginx

CentOS 7 编译安装 Nginx 背景下载 Nginx 源码包安装依赖包编译添加环境变量添加守护查考文献 背景 一开始使用 docker 搭建了一个 web 服务器&#xff0c;但是由于 docker 不太方便的部署 TLS 证书&#xff0c;故使用 Nginx 做反向代理&#xff0c;实现 https 连接。 下载 N…

观成科技-基于自适应学习的人工智能加密流量检测技术

1.前言 人工智能技术的广泛应用正在深刻改变我们的生活。在网络安全领域&#xff0c;基于机器学习的检测技术也应用在许多场景中。随着信息技术的迅猛发展和数字化转型的深入推进&#xff0c;加密技术逐渐成为保障网络安全和数据隐私的核心手段&#xff0c;而基于机器学习的检…

LeetCode 面试经典150题 274.H指数

题目&#xff1a; 给你一个整数数组 citations &#xff0c;其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义&#xff1a;h 代表“高引用次数” &#xff0c;一名科研人员的 h 指数 是指他&#xff08;她…

滑块验证码

1.这里针对滑块验证给了一个封装的组件verifition&#xff0c;使用直接可以调用 2.组件目录 3.每个文件的内容 3.1 Api文件中只有一个index.js文件&#xff0c;用来存放获取滑块和校验滑块结果的api import request from /router/axios//获取验证图片 export function reqGe…

影响交易收益的因素有哪些?

在尝试做交易时&#xff0c;你可能会问自己一个问题&#xff1a;交易一天能赚多少钱&#xff1f;“如果我全职投入交易&#xff0c;一天能赚多少&#xff1f;”或者更广泛地说&#xff0c;“交易能为我带来怎样的财富&#xff1f;”这些问题本质上都充满了不确定性&#xff0c;…

upload-labs-pass01

1.安装好环境进入关卡&#xff08;记得打开小皮&#xff09; 2.可以看到第一关是要求上传图片&#xff0c;但是同时限制了图片类型&#xff0c;那么如果我们将木马写入图片&#xff0c;但是类型又不在白名单&#xff0c;就要想办法绕过 3.可以看到这里的要求是有check&#xff…

计算机组成原理——自己制作一个cpu

cpu包括单周期cpu、中断cpu、多周期cpu 代码实现之后在实验箱看效果&#xff0c;并且看波形图 单周期波形 中断cpu 多周期cpu 1.单周期CPU总体电路图 如图是一个简单的基本上能够在单周期CPU上完成所要求设计的指令功能的数据通路和必要的控制线路图。其中指令和数据各存储在不…

怎么批量去掉文件名中的空格?

怎么批量去掉文件名中的空格&#xff1f;在日常工作和生活中&#xff0c;我们经常会遇到文件名中含有空格的情况。这些空格可能是因为拷贝、重命名或其他操作时产生的&#xff0c;给文件的管理和识别带来了一定困扰。为了更好地整理和管理文件&#xff0c;批量去掉文件名中的空…

一文速通半监督学习(Semi-supervised Learning):桥接有标签与无标签数据

一文速通半监督学习&#xff1a;桥接有标签与无标签数据 前言背景补充&#xff1a;监督学习、半监督学习、无监督学习半监督学习(Semi-supervised Learning)的魔法一、半监督学习的三个常见的基本假设1. 连续性假设&#xff08;Smoothness Assumption&#xff09;2. 聚类假设&a…

【视频图像取证篇】模糊图像增强技术之锐化类滤波场景应用小结

【视频图像取证篇】模糊图像增强技术之锐化类滤波场景应用小结 模糊图像增强技术之锐化类滤波场景应用小结—【蘇小沐】 &#xff08;一&#xff09;锐化类滤波器 模糊消除类滤波器&#xff08;Remove blur / Unsharpness&#xff09;。 通用去模糊滤波器&#xff1a;针对大…

多线程在线检测网速流量HTML源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 多线程在线检测网速流量html源码&#xff0c;测试您的网速&#xff0c;多地查询您的IP地址&#xff0c;同时具备网络延迟实时检测&#xff0c;流量杀手&#xff0c;流量消耗器&#x…

申请Github Education获取免费Copilot权限(2024.3.18实测成功)

起因&#xff1a;旧帐户Copilot权限被封 我已经离开Github Copilot就无法独自耐着性子写代码了&#xff08;懒惰AI成瘾性&#xff09;&#xff0c;这两天Github Copilot不知道为什么在大规模封号&#xff0c;我不幸也被封号了&#xff08;禁用掉了Github Copilot权限&#xff…

微信自动回复的好处,如何设置

自动回复的好处&#xff1a; 1、支持自定义不重复触发时间和生效时间段&#xff0c;使得回复效果更为智能&#xff1b; 2、支持多个微信设置&#xff0c;并可直接导入素材库内容&#xff0c;以提高工作效率&#xff1b; 3、具备多个关键词和多条回复内容&#xff0c;从而使自…

Acwing.1360 有序分数(递归or最小公因数)

题目 给定一个整数 N&#xff0c;请你求出所有分母小于或等于 N&#xff0c;大小在 [0,1]范围内的最简分数&#xff0c;并按从小到大顺序依次输出。 例如&#xff0c;当 N5时&#xff0c;所有满足条件的分数按顺序依次为&#xff1a; 输入格式 共一行&#xff0c;包含一个整…

十二、Transformer(Attention Mechanism)

参考Transformer详解 和 Transforner模型详解 1 Transformer 整体结构 Transformer 由 Encoder 和 Decoder 两个部分组成&#xff0c;Encoder 和 Decoder 都包含 6 个 block。 ​ 2 Transformer 局部结构 2.1 输入层 Transformer 中的输入层是由单词的 Word Embedding 和 …

传统电力运维企业的数字化转型案例

一. 传统电力运维企业面临的主要问题 上海某电力集团企业下属有成套设备公司、电力工程公司&#xff0c;依托于自身的设备制造和工程服务能力&#xff0c;以及多年积累的终端客户资源&#xff0c;几年前该公司成立了电力运维服务公司进入用户侧电力托管运维服务行业。 该公司…

4-激活函数:给机器注入灵魂

声明 本文章基于哔哩哔哩付费课程《小白也能听懂的人工智能原理》。仅供学习记录、分享&#xff0c;严禁他用&#xff01;&#xff01;如有侵权&#xff0c;请联系删除 目录 一、知识引入 &#xff08;一&#xff09;背景 &#xff08;二&#xff09;激活函数 &#xff08…

vulhub中DNS域传送漏洞复现

DNS协议支持使用axfr类型的记录进行区域传送&#xff0c;用来解决主从同步的问题。如果管理员在配置DNS服务器的时候没有限制允许获取记录的来源&#xff0c;将会导致DNS域传送漏洞。 环境搭建 Vulhub使用Bind9来搭建dns服务器&#xff0c;但不代表只有Bind9支持AXFR记录。运行…

知识管理系统(KMS)和AI的融合十大场景

我向AI问了一个问题&#xff0c;KMS和AI融合有哪些场景&#xff0c;不得不说AI越来越强大了&#xff0c;他给我列出了十个场景&#xff0c;老铁们知道有哪些可以落地的吗&#xff1f; 将知识管理系统&#xff08;KMS&#xff09;与人工智能&#xff08;AI&#xff09;融合有着广…