C++ 多态学习笔记(下)

news2024/11/23 3:40:35

开始新的学习之前,我们先通过一段涉及继承、多态的 代码来回忆、加深理解。

Animal作为基类,我们要给每种动物实例化出sound()的模块,因为Animal在实际意义上没什么好实例化的,所以设计成抽象类。 

class Animal
{
public:
	virtual void sound() const = 0;//后面重写的函数都必须用const修饰
};

class Cat : public Animal
{
public:
	virtual void sound() const
	{
		cout << "喵喵" << endl;
	}
};

class Dog : public Animal
{
public:
	virtual void sound() const
	{
		cout << "汪汪" << endl;
	}
};

void AnimalSound(const Animal& anm)//Animal不能实例化对象,但是可以生成指针或者引用
{
	anm.sound();
}

虽然Animal不能实例化出对象,但是可以声明出一个抽象类的引用,来作为施展多态魔法的条件。这里的Animal就是作为一个像工具人一样的类,本身就不打算实例一个Animal,因为必须要指定出具体是什么动物之后,sound()这个函数才有意义。


1. 虚函数表

上一文的最后一个例题提到了虚函数表指针(_vfptr),虚函数表是一个指针数组,虚函数的地址都被放进了虚函数表,虚函数表也被简称为虚表。

关于虚函数、虚函数表、虚函数表指针的关系,我们有以下说明:

虚函数和其他成员函数一样,都是存在代码段的。

可通过比较虚拟函数和一般函数的地址差距:

三个函数的地址:

打印地址可发现,Func1 Func2 Func3的位置还是很接近的,都存在代码段。

而虚表的地址不一定,比如在vs下虚表就是存在常量区的,而虚表的指针才是存在对象中的。


2. 多态原理

再来观察虚函数表的存在:

Func1和Func2作为虚函数,其函数指针会被存进虚函数表;反之编译器也能通过

但是Func3没有在虚函数表中,而是存在符号表中。

Base对象作为基类,设其子类叫Derive,并且在Derive中只重写了Func1 , 没有重写Func2;并且我们发现:

子类的虚表和父类的虚表不是一个虚表,调用函数时只管去对应的虚表找出新的Func1

所以虚函数的重写也叫作覆盖,覆盖就是指虚表中虚函数
的覆盖。重写是语法的叫法,覆盖是原理层的叫法。

派生类和基类的Func1地址不一样,而Func2的地址是一样的,因为Func2没有重写。

派生类的虚表中会放没有重写的虚函数地址(与基类中的一样)和自己重写出来的虚函数地址。

普通函数是在编译或者链接(声明定义分离)时,根据函数名修饰规则,通过符号表找到函数的地址。

                            

因此,我们也称多态为动态绑定,

在程序运行期间,根据具体拿到的类型确定程序的具体 行为,调用具体的函数;
在程序编译期间确定了程序的行为 也称为静态多态
比如:函数重载

然后我们也可以尝试去理解为什么需要一个父类的引用或者指针就能调用对应的内容:

                              

派生类本来就是包含基类的,但是两种类里面的虚表不同,Base对象直接通过指针和引用访问,派生类也是直接使用父类的指针引用才能访问虚函数表。

这样底层逻辑就通了,不管是基类还是派生类,都是通过同一类型的指针去访问虚函数表调用函数的。

同一个类型的变量共享同一个虚表。

常见易错:

类域之后直接用类域中的,不会再去调用多态。

比如下图就不是运行绑定:

复习:

虚函数和普通函数一样,都是存在代码段的。

不同的是,虚函数的函数指针会被放在虚表中的。

类里面存的是虚表的地址。而虚表根据平台的不同可能存在静态区等,C++没有严格规定。

我们通过以下方式(指针和指针之间可以强转)得到虚表的地址:

          

或者再创建几个不同存储位置的变量,打印不同类型的变量地址,比较大小:

                                          

对象是在栈中,虚表被处理在常量区,虚表指针在对象中所以也在栈中,虚函数在代码段。


3. 静态多态

函数重载和模版也算是静态多态,在编译时就能确定的多态

练习:

class Base1 {  public:  int _b1; };
class Base2 {  public:  int _b2; };
class Derive : public Base1, public Base2 { public: int _d; };
int main(){
 Derive d;
 Base1* p1 = &d;
 Base2* p2 = &d;
 Derive* p3 = &d;
 return 0;
}

 

考察的是切割部分的知识,在多继承时,谁先继承谁在前面,p1会被切割为只管d的Base1部分,p2会被切割为只管d的Base2部分,p3则是管理整个d的部分。 

                                               

故选C

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

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

相关文章

又考了两个Oracle认证:RAC和DataGuard,文末送资料

号主姚远目前已经拥有Oracle的认证超过20个了&#xff0c;最近又考了两个Oracle 19c的认证&#xff0c;是RAC和DataGuard。其实内容和12c没有太大的区别&#xff0c;但题目依然很难&#xff0c;很多选项模拟两可&#xff0c;需要对相关概念非常清楚才能通过考试。姚远的运气不错…

Linux网络:应用层协议http/https

认识URL URL是我们平时说的网址 eg&#xff1a;http常见的URL http://user:passwww.example.jp:80/dir/index.htm?uid1#ch1 注意&#xff1a; 服务器地址就是域名&#xff0c;相当于服务器ip地址 像http服务绑定80端口号&#xff0c;https服务绑定443端口。ssh服务端口绑定…

EasyCVR无法启动并报错“error while loading shared libraries”,如何解决?

安防监控/视频汇聚平台EasyCVR视频管理系统以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力&#xff0c;为各行各业的视频监控需求提供了优秀的解决方案。通过简单的配置和操作&#xff0c;用户可以轻松地进行远程视频监控、存储和查看&#xff0c;满足…

Python操作ES集群API(增删改查等)

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 学习B站博主教程笔记&#xff1a; 最新版适合自学的ElasticStack全套视频&#xff08;Elk零基础入门到精通教程&#xff09;Linux运维必备—Elastic…

Vue组件:插槽的使用

在实际开发中&#xff0c;子组件往往只提供基本的交互功能&#xff0c;而内容是有父组件来提供的。为此&#xff0c;Vue.js 提供了一种混合父组件内容和子组件模板的方式&#xff0c;这种方式称为内容分发。 1、基本用法 Vue.js 参照当前 Web Components 规范草案实现了一套内…

和 InternLM 解锁“谁是卧底”新玩法

本文来自社区投稿&#xff0c;作者LangGPT联合发起人、东北大学在读博士生王明 在大模型技术日益普及的今天&#xff0c;AI 的应用已经渗透到各个领域&#xff0c;带来了无数创新和乐趣。今天&#xff0c;我们将一起探索如何搭建一个 AI 版的“谁是卧底”游戏。通过 InternStud…

【Unity基础】Input中GetAxis和GetAxisRaw的区别

一句话描述&#xff1a;GetAxis使用了平滑过渡&#xff0c;而GetAxisRaw是直接改变。 在Unity中&#xff0c;Input.GetAxisRaw 和 Input.GetAxis 都用于获取输入设备的轴向输入&#xff08;例如键盘、鼠标或手柄的摇杆&#xff09;&#xff0c;但它们的工作方式和返回值有细微…

GPU 服务器性能评估:多维度深度探索

在深度学习的浩瀚宇宙中&#xff0c;GPU 服务器犹如一颗璀璨的星辰&#xff0c;以其无与伦比的计算能力和效率引领着技术进步的浪潮。为了充分挖掘这一强大工具的潜力&#xff0c;我们需深入探寻其性能评估的奥秘&#xff0c;这不仅仅是对单一指标的简单堆砌&#xff0c;而是从…

从虚拟现实到元宇宙:Facebook引领未来社交的下一步

随着科技的迅猛发展&#xff0c;社交媒体正在经历一场深刻的变革。从最初的文本和图片交流&#xff0c;到如今的沉浸式虚拟现实&#xff08;VR&#xff09;和即将到来的元宇宙&#xff0c;社交互动的方式正在发生根本性的变化。作为行业领军者&#xff0c;Facebook&#xff08;…

3GPP协议入门——物理层基础(一)

1. 频段/带宽 NR指定了两个频率范围&#xff0c;FR1&#xff1a;通常称Sub 6GHz&#xff0c;也称低频5G&#xff1b;FR2&#xff1a;通常称毫米波&#xff08;Millimeter Wave&#xff09;&#xff0c;也称高频5G。 2. 子载波间隔 NR中有15kHz&#xff0c;30kHz&#xff0c;6…

数据库类型有哪些?

根据存储方式的不同&#xff0c;数据库可以分为不同种类。每种类型的数据库&#xff0c;都有各自使用场景以及不同的产品。 ​ 关系型数据库 关系型数据库&#xff08;RDBMS&#xff09;基于关系模型&#xff0c;通过表&#xff08;Table&#xff09;的形式来组织数据&#xf…

利士策分享,如何规划多彩的大学生活?

利士策分享&#xff0c;学习规划多彩的大学生活 踏入大学&#xff0c;如同开启一场充满未知与可能的旅程。 为了让这段旅程不仅充满学术的熏陶&#xff0c;还洋溢着生活的多彩与人际的和谐&#xff0c;我们需要精心规划&#xff0c;积极行动。 一、多彩规划&#xff1a;点亮大学…

双指针的运用

一、双指针 双指针 常⻅的双指针有两种形式&#xff0c;⼀种是对撞指针&#xff0c;⼀种是左右指针。 1.1 对撞指针&#xff1a;⼀般⽤于顺序结构中&#xff0c;也称左右指针。 • 对撞指针从两端向中间移动。⼀个指针从最左端开始&#xff0c;另⼀个从最右端开始&#xff…

一文揭秘:从零开发一套中小型医院的云HIS系统,需要多少开发成本?

从零开发一套中小型的云HIS&#xff08;医院信息系统&#xff09;系统&#xff0c;首先要组建团队&#xff0c;包括招聘、培训、设备购置&#xff0c;然后要经历需求分析、系统设计、编码、测试等多个阶段&#xff0c;这会消耗大量的时间&#xff0c;其开发成本会受到多种因素的…

《凡人歌》重塑现实主义爆款,正午阳光终于“杀”回来了

2024年的现实主义爆款&#xff0c;出自正午阳光之手。 今年剧集市场一个明显的变化在于&#xff0c;最贴近时代生活、最有“爆款潜质”的现实主义题材电视剧的缺位。根据云合数据&#xff0c;截止到2024年9月&#xff0c;年榜前十中没有一部现实主义大剧&#xff0c;古装剧却多…

在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境

目录 在线编程实现&#xff01;如何在Java后端通过DockerClient操作Docker生成python环境 一、为什么要用后端程序操作Docker 二、安装Docker 1、安装Docker 2、启动Docker 三、DockerClient与CMD操作Docker的区别 四、干货&#xff01;如何使用DockerClient实现在线编程…

通过信息架构提升商业智能:实现数据驱动创新的策略与方法

拥抱数据驱动时代 在当前的数字化转型浪潮中&#xff0c;数据已成为企业最重要的资产之一。全球范围内的网络巨头通过精细的数据管理和分析&#xff0c;已成功颠覆了传统行业。这些企业的成功不仅源于他们掌握了大量数据&#xff0c;还因为他们能有效地利用这些数据来做出精准…

研一小白读论文记录,计算机视觉,Transformer

论文是IEEE收录的一篇论文《CrossFormer: A Versatile Vision Transformer Hinging on Cross-Scale Attention》&#xff08;《基于跨尺度自注意力机制的多功能视觉Transformer》&#xff09; 泛读完之后最大的感悟有以下几点&#xff1a; 1、文章在实验的结果中呈现了大量的…

Getty Images推AI训练样本:3750张高质量照片免费开放

近日&#xff0c;全球领先的商业图库Getty Images发布了一项重大决策&#xff0c;宣布将为AI开发者提供一份包含3750张高分辨率照片的免费训练数据集。这份详尽的数据集覆盖了商业、教育、医疗健康、运动健身、物品物体、插图图标等15个不同领域&#xff0c;目的在于助力AI技术…

unity UGUI高性能飘字解决方案(对象池+合并网格)

本方案仅供参考 从需求出发 游戏类型&#xff1a;微信小游戏 帧数限定&#xff1a;60 已知的几种方案&#xff1a; 1:场上只存在一个mesh&#xff0c;每帧把所有字绘制到一个mesh。 优点&#xff1a;每帧都重绘&#xff0c;高度定制化&#xff0c;可以随意添加、删除。 …