【C++】多态

article/2025/7/22 13:00:10

目录

1. 多态的概念

2. 多态的定义和实现

2.1 构成多态的条件

2.2 虚函数

2.3 虚函数的重写(覆盖)

2.4 小试牛刀

3. 重载/重写/隐藏的对比

4. 纯虚函数和抽象类

5.多态的原理

5.1 虚表

5.2 虚表指针

5.3 对比虚函数、虚表、虚表指针

1. 多态的概念

多态(Polymorphism)是面向对象编程的三大基本特征(继承,多态,封装)之一,指的是同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

多态的字面意思是"多种形态",在编程中表现为:

同一个接口,使用不同的实例而执行不同操作

同一消息可以根据发送对象的不同而采用多种不同的行为方式

2. 多态的定义和实现

2.1 构成多态的条件

●必须是基类指针或者引用调用虚函数

●被调用的函数必须是虚函数,并完成了虚函数的重写/覆盖

2.2 虚函数

基类中加virtual修饰的类成员函数就是虚函数。

如图中的shout函数:

2.3 虚函数的重写(覆盖)

派生类中有有一个与基类完全相同(即返回类型、函数名、参数列表完全相同)的虚函数,则称派生类的虚函数重写了基类的虚函数。

注意:重写虚函数时,派生类中的虚函数可以不加virtual关键字,也可以构成重写,因为这样也可以构成重写,因为基类的虚函数属性被派生类虚函数继承了,但是这种写法并不规范。

2.4 小试牛刀

下面我们来试着做一道题,加深我们对虚函数的理解

下面的程序输出结果是什么:

 class A{public:virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}virtual void test(){ func();}};class B : public A{public:void func(int val = 0){ std::cout<<"B->"<< val <<std::endl; }};int main(int argc ,char* argv[]){B*p = new B;p->test();return 0;}

解析:

p->test() 调用 A::test()(test() 是继承自 A 的虚函数,但未被 B 重写)。

A::test() 内部调用 func(),由于 func() 是虚函数且 p 指向 B 对象,实际调用 B::func()。

在 C++ 中,默认参数是静态绑定(编译时确定),而虚函数是动态绑定(运行时确定)。因此,当通过基类指针或引用调用虚函数时:调用的是派生类(实际对象类型)的重写版本。使用的是基类函数声明的默认值,而非派生类的默认值。

所以默认参数 val 的值来自 A::func() 的定义(val = 1),而非 B::func() 的 val = 0。

因此,执行 B::func(1),输出 B->1

3. 重载/重写/隐藏的对比

重载:两个函数在同一作用域;函数名相同,参数相同,参数类型或个数不同;返回值可同可不同

重写(覆盖):两个函数分别在父类和子类不同作用域;函数名,参数,返回值必须相同,协变例外;两个函数都必须是虚函数

隐藏:两个函数分别在父类和子类不同作用域;函数名相同,只要不构成重写,就是隐藏;父子类的成员变量相同也是隐藏

4. 纯虚函数和抽象类

在虚函数后面加上=0,这类函数就是纯虚函数。纯虚函数语法上是可以定义实现的,但是也没必要,因为要被派生类重写,所以一般只需声明即可。

包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象。如果派生类继承抽象类后不重写纯虚函数,那么派生类也是抽象类。

//抽象类
class Car
{
public://纯虚函数virtual void Drive() = 0;
};//库里南
class Cullinan:public Car
{
public:virtual void Drive(){cout << "Cullinan" << endl;}
};//宾利
class Bentley :public Car
{
public:virtual void Drive(){cout << "Bentley" << endl;}
};int main()
{//Car car;//抽象类不能实例化Car* pC = new Cullinan;pC->Drive();Car* pB = new Bentley;pB->Drive();return 0;
}

5.多态的原理

5.1 虚表

虚表(vTable):存储虚函数地址的表,每个类一份。

虚表是编译器为每个包含虚函数的类创建的一个隐藏数据结构,它是一个函数指针数组,存储了该类所有虚函数的实际地址。

虚表的特点包括:

每个具有虚函数的类都有自己的虚表

虚表在编译阶段生成,并存储在程序的只读数据段

派生类的虚表会继承基类的虚表内容,并替换掉被重写的虚函数地址

5.2 虚表指针

虚表指针(vptr):每个对象内部隐藏的指针,指向所属类的虚表。

虚表指针特点:

在对象构造时被初始化,指向该对象所属类的虚表

通常位于对象内存布局的最前面

大小通常为一个指针的大小(32位系统4字节,64位系统8字节)

在VS2022中调试下列代码

class animal
{
public:virtual void shout(){cout << "喊叫" << endl;}
};class cat : public animal
{
public:virtual void shout(){cout << "喵喵" << endl;}
};void say(animal& an)
{an.shout();
}int main()
{animal a;cat c;say(a);say(c);return 0;
}

5.3 对比虚函数、虚表、虚表指针


http://www.hkcw.cn/article/dJeqgnNlIX.shtml

相关文章

肖战演活了藏海 台湾观众好评如潮

正在热播的电视剧《藏海传》在台湾引起了广泛关注,不仅获得了岛内观众的一致好评,也得到了媒体的争相报道。这部剧以其精良的制作、紧凑的情节以及所展现的中华文化深深吸引了台湾观众。5月31日,“肖战演藏海在台湾刷屏”这一话题冲上了微博热搜榜。近年来,大陆电视剧在台湾…

C# 多线程编程全面指南:从基础到高级实践

在现代软件开发中&#xff0c;多线程编程已成为提升应用程序性能的关键技术。C# 作为.NET平台的主力语言&#xff0c;提供了丰富的多线程处理机制。本文将全面介绍C#中的多线程编程技术&#xff0c;从基础概念到高级应用&#xff0c;帮助开发者掌握这一重要技能。 一、多线程基…

PASCAL VOC数据集/AI标注/算法训练推理EasyAML如何实现“数据不出域”的本地化AI标注训练

在当今数字化转型的大潮中&#xff0c;众多企业对AI视觉技术的需求日益增长。无论是制造业的产品质量检测、物流行业的货物识别与车辆管理&#xff0c;还是安防领域的视频监控与分析&#xff0c;AI视觉技术的应用场景广泛且多样。然而&#xff0c;在实际应用过程中&#xff0c;…

Linux系统中的shell脚本基础知识

1.shell脚本基础&#xff1a;shell脚本是文本的一种&#xff0c;属于可以运行的文本&#xff0c;shell脚本的内容是由逻辑和数据组成的。 2.shell脚本意义&#xff1a;shell脚本语言是实现Linux/unix系统管理及自动化运维所必备的重要工具。 常见shell种类&#xff1a;Bourne …

C++修炼:位图和布隆过滤器

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 1、引言 在计算机科学…

贾冰瘦脱相 压力给到沈腾了 减肥热潮席卷娱乐圈

5月31日,演员贾冰的妻子发布了一段视频,祝福大家端午节快乐,并配文“从此我家多了个瘦子”。从两人合影中可以看出,贾冰明显瘦了很多。评论区里很多人询问他如何瘦下来的,甚至有人表示他瘦得有些认不出来了。贾冰妻子回复说,主要是通过少吃(一天一顿)和运动达到的。贾冰…

AdaCtrl:自适应可控Reasoning,可降10~90%推理长度!!

摘要&#xff1a;现代大型推理模型通过运用复杂的推理策略展示了令人印象深刻的解决问题能力。然而&#xff0c;它们常常难以平衡效率和有效性&#xff0c;经常为简单问题生成不必要的冗长推理链。在本研究中&#xff0c;我们提出了AdaCtrl&#xff0c;这是一个新颖的框架&…

格式工厂 FormatFactory v5.20.便携版 ——多功能媒体文件转换工具 长期更新

—————【下 载 地 址】——————— 【​本章下载一】&#xff1a;https://pan.xunlei.com/s/VORWF3Q7D0eCVV06LHbzheD-A1?pwdjikz# 【​本章下载二】&#xff1a;https://pan.quark.cn/s/8ee59ed83658 【百款黑科技】&#xff1a;https://ucnygalh6wle.feishu.cn/wiki/…

贾冰瘦到脱相 网友:压力给到沈腾 减肥风潮席卷娱乐圈

5月31日,演员贾冰的妻子发布了一段视频,祝福大家端午节快乐,并配文“从此我家多了个瘦子”。在两人合影中,贾冰明显瘦了很多。评论区里大家都在问他是如何瘦下来的,甚至有人觉得他瘦得都快认不出来了。对此,贾冰妻子回复说,主要是通过少吃(一天一顿)和运动来减肥的。贾…

多地机关食堂端午向社会开放 节日共享美食

端午假期,全国多地政府机关食堂面向社会公众开放。重庆市荣昌区政府机关食堂在5月31日中午如约向游客开放,首日吸引了超过3000名游客前来体验。该食堂特别推出了61元的“六一”家庭套餐,包括荣昌卤鹅、黄凉粉等特色菜品,并新增了粽子和儿童喜欢的薯条、鸡腿、鸡块等小吃,让…

vscode实用配置

前端开发安装插件&#xff1a; 1.可以更好看的显示文件图标 2.用户快速打开文件 使用步骤&#xff1a;在html文件下右键点击 open with live server 即可 刷力扣&#xff1a; 安装这个插件 还需要安装node.js即可

武夷山耗资千万建不锈钢天池?假 AI谣言混淆视听

近日,武夷山市委网信办工作人员在日常网络舆情巡查中发现,有网民在某网络平台上发布信息,称无人机航拍到武夷山耗资千万修建的“不锈钢天池”。经武夷山国家公园福建管理局核实,该文章为不实信息。文中提到的“不锈钢天池”并不位于武夷山国家公园范围内,而是位于重庆武陵…

战国足前印尼集训着重练习定位球 强化任意球战术

印尼队在巴厘岛的集训中加强了定位球战术的训练。此前客场与国足的交手中,印尼队曾利用任意球完成破门。这次集训,克鲁伊维特招入了维克里、萨尤里兄弟、利利帕利和普特拉等前锋,这些球员速度快、脚下技术好,能够丰富球队的进攻套路,并在前场积极逼抢,阻滞国足的防守反击…

网页自动化部署(webhook方法)

实现步骤&#xff1a; 宝塔安装宝塔WebHook 2.5插件。 github 上配置网页仓库&#xff08;或可在服务器的网页根目录clone&#xff09;。 配置宝塔WebHook 2.5 添加hook脚本&#xff1b; 编辑添加syncJC脚本&#xff1b; #!/bin/bash # 定义网站根目录 WEBROOT"/www…

Redis持久化

文章目录 持久化1、RDB1&#xff09;触发机制2&#xff09;bgsave命令的运行流程3&#xff09;RDB文件的处理4&#xff09;RDB的优缺点 2、AOF1&#xff09;开启AOF2&#xff09;AOF工作流程3&#xff09;AOF同步策略4&#xff09;重写机制5&#xff09;重写机制的运行流程 持久…

循环流化床锅炉关键技术设计与优化路径

摘要 循环流化床锅炉&#xff08;CFB&#xff09;作为高效清洁燃烧技术的代表&#xff0c;在燃煤发电、生物质利用等领域具有显著优势。本文从设计原理出发&#xff0c;详细分析物料循环系统、燃烧室结构、受热面布置等核心设计要素&#xff0c;并提出针对不同燃料特性的优化方…

PyTorch-Transforms的使用(二)

对图像进行处理 安装open cv ctrlP 看用法 ToTensor的使用 常见的Transforms 归一化的图片 两个长度为三的数组&#xff0c;分别表示三个通道的平均值和标准差 Resize&#xff08;&#xff09; Compose&#xff08;&#xff09; 合并执行功能&#xff0c;输入进去一个列表&a…

【萌笔趣棋】网页五子棋项目测试报告

目录 一.项目介绍 &#xff08;一&#xff09;项目简介 &#xff08;二&#xff09;功能介绍 &#xff08;三&#xff09;页面展示 1.注册页面 2.登录页面 3.游戏大厅页面 4.游戏房间页面&#xff08;对战&#xff09; 二.功能测试 &#xff08;一&#xff09;出现的…

乌克兰袭击俄轰炸机基地画面曝光 大胆军事行动震动俄乌

乌克兰官员周日宣布,乌克兰军队对俄罗斯境内深处的多个军用机场进行了大规模无人机袭击。这些机场是用于进行空袭的战略轰炸机基地,这次行动被认为是自俄乌冲突爆发以来乌克兰军队最大胆的一次军事行动。此次代号为“蛛网”的袭击行动经过一年半的准备。乌克兰无人机的目标包…

卡友护送青藏线司机骨灰回家 爱心跨越2400公里

河南46岁的卡车司机常志荣在青海五道梁地区因高原缺氧离世,家中还有六个孩子需要抚养。为了省下一罐氧气的钱,他在出发前只购买了一罐氧气。五道梁地区海拔4665米,含氧量不足海平面的一半,自然环境极其恶劣。得知消息后,多名卡车司机自费远赴2000多公里护送常志荣的骨灰及…