c++多态
1.多态的概念
通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。
2.多态的定义及实现
2.1多态的构成条件
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。 Person对象买票全价,Student对象买票半价。
在继承中要构成多态需要满足两个条件:
- 必须通过基类的指针或者引用调用虚函数。
- 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写
例子:
2.2 虚函数
虚函数:即被virtual修饰的类成员函数称为虚函数。
class Person {public:virtual void BuyTicket() { cout << "买票-全价" << endl;}};
2.3虚函数的重写
虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类 型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。
class Person
{public:virtual void BuyTicket() { cout << "买票-全价" << endl; }
};class Student : public Person
{public:
//子类对基类虚函数进行了重写virtual void BuyTicket() { cout << "买票-半价" << endl;
}
注 :在重写基类虚函数时,派生类的虚函数在不加virtual关键字也可以,但是该种写法不是很规范。
2.4虚函数重写的两个例外:
2.4.1协变(基类与派生类虚函数返回值类型不同
派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引 用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。
class A{};
class B : public A {};class Person {public:
//返回值是基类A*virtual A* f() {return new A;}};class Student : public Person {public:
//返回值是派生类B* 此时这个虚函数尽管返回值不同,仍然完成虚函数重写virtual B* f() {return new B;}};
2.4.2析构函数的重写(基类与派生类析构函数的名字不同)
如果基类的析构函数为虚函数,此时派生类析构函数只要定义就构成析构函数的重写。虽然函数名不相同,看起来违背了重写的规 则,但最后编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处 理成destructor。
class Person{
public:virtual ~Person() {cout << "~Person()" << endl;}};
class Student : public Person {public:virtual ~Student() { cout << "~Student()" << endl; }};
int main(){Person* p1 = new Person;Person* p2 = new Student;delete p1;//因为完成了虚函数的重新,所以p1指向的对象是Person,调用~Rerson();delete p2;//虽然P2是Person*,但多态与指定的对象有关,所以调用~Student();return 0;}
注: 多态与指向的对象有关,指向那个对象就调用它的虚函数。不满足多态:与 调用的对象的类型有关,类型是什么就调用它的虚函数。
2.5 C++11 override 和 final
C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来 debug,因此:C++11提供了override和final两个关键字,可以帮助用户检测是否重写。
2.5.1. final:修饰虚函数,表示该虚函数不能再被重写
{public:virtual void Drive() final {}};class Benz :public Car{public:virtual void Drive() {cout << "Benz-舒适" << endl;}};
2.5.2 override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错
class car{
public:virtual void Drive(){}};class Benz :public Car {public:virtual void Drive() override {cout << "Benz-舒适" << endl;}}
2.6 函数重载、覆盖(重写)、隐藏(重定义)的对比

3.抽象类
3.1概念
在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类 不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承
class Car{public:virtual void Drive() = 0;};class Benz :public Car{public:virtual void Drive(){cout << "Benz-舒适" << endl;}
3.2 接口继承和实现继承
- 普通函数的继承是一种实现继承
- 虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口.
4.多态的原理
4.1虚函数表
// sizeof(Base)是多少?
class Base{public:virtual void Func1(){cout << "Func1()" << endl;}private:int _b = 1;}
注:在这里class Base 并不是只有一个整形int 4个字节,因为 void Func1()前面加了 virtual 是虚函数,则除了_b成员,还多一个__vfptr(虚函数指针)放在对象的前面,这样sizeof(Base)为8个字节。
对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代表 function)。一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中, 虚函数表也简称虚表,

- 虚函数表本质是一个存虚函数指针的指针数组,一般情况这个数组最后面放了一个nullptr。
4.2虚函数的共用

注:Base这个类有两个虚函数,所以虚函数表存放了两个指针,并且Fun1()函数指针为0x0b31087

4.3虚函数存在哪的?虚表存在哪?

虚函数会被编译成指令放在代码段 ,而上面我们也提到过可以理解虚函数共用一个虚函数表(基类b对象和派生类d对象虚表是不一样的,),即放在公共部分,所以在代码段。
4.4多态的原理

5.动态绑定与静态绑定
- 静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态,比如:函数重载
- 动态绑定后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态。
6.例子 :以下程序输出结果是什么?
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;
}
前面我们也提过虚函数的继承是一个接口继承 ,所以实际上继承的是 void func(int val=1),
函数体则为{ std::cout<<"B->"<< val <<std::endl; }。所以程序运行结果应该为B—>1.
相关文章:
c++多态
1.多态的概念 通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。 2.多态的定义及实现 2.1多态的构成条件 多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为…...
ResNeSt: Split-Attention Networks 参考论文
参考文献 [1] Tensorflow Efficientnet. https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet. Accessed: 2020-03-04. 中文翻译:[1] TensorFlow EfficientNet. https://github.com/tensorflow/tpu/tree/master/models/official/efficien…...
Blazor-选择循环语句
今天我们来说说Blazor选择语句和循环语句。 下面我们以一个简单的例子来讲解相关的语法,我已经创建好了一个Student类,以此类来进行语法的运用 因为我们需要交互性所以我们将类创建在*.client目录下 if 我们做一个学生信息的显示,Gender为…...
从AD的原理图自动提取引脚网络的小工具
这里跟大家分享一个我自己写的小软件,实现从AD的原理图里自动找出网络名称和引脚的对应。存成文本方便后续做表格或是使用简单行列编辑生成引脚约束文件(如.XDC .UCF .TCL等)。 我们在FPGA设计中需要引脚锁定文件,就是指示TOP层…...
苍穹外卖使用MyBatis-Plus
系列博客目录 文章目录 系列博客目录一、修改sky-take-out项目的pom.xml文件1.修改lombok依赖的版本号2.修改spring-boot-starter-parent父工程的版本号3.增加依赖 二、修改sky-server模块的pom.xml文件1.增加mysql连接的依赖(版本为8.0以上)2.增加两个依…...
Baklib引领数字化内容管理转型提升企业运营效率
内容概要 在数字化迅速发展的背景下,企业正面临着前所未有的内容管理挑战。传统的内容管理方式已难以适应如今的信息爆炸,企业需要更加高效、智能的解决方案以应对复杂的数据处理需求。Baklib作为行业的先锋,以其创新技术对数字化内容管理进…...
【PyTorch】4.张量拼接操作
个人主页:Icomi 在深度学习蓬勃发展的当下,PyTorch 是不可或缺的工具。它作为强大的深度学习框架,为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术,能够处理复杂的数据模式。通过 PyTorch࿰…...
MySQL--》深度解析InnoDB引擎的存储与事务机制
目录 InnoDB架构 事务原理 MVCC InnoDB架构 从MySQL5.5版本开始默认使用InnoDB存储引擎,它擅长进行事务处理,具有崩溃恢复的特性,在日常开发中使用非常广泛,其逻辑存储结构图如下所示, 下面是InnoDB架构图…...
Visio2021下载与安装教程
这里写目录标题 软件下载软件介绍安装步骤 软件下载 软件名称:Visio2021软件语言:简体中文软件大小:4.28G系统要求:Windows10或更高,64位操作系统硬件要求:CPU2GHz ,RAM4G或更高下载链接&#…...
实战纪实 | 真实HW漏洞流量告警分析
视频教程在我主页简介和专栏里 目录: 一、web.xml 文件泄露 二、Fastjson 远程代码执行漏洞 三、hydra工具爆破 四、绕过验证,SQL攻击成功 五、Struts2代码执行 今年七月,我去到了北京某大厂参加HW行动,因为是重点领域—-jr&…...
【AI论文】扩散对抗后训练用于一步视频生成总结
摘要:扩散模型被广泛应用于图像和视频生成,但其迭代生成过程缓慢且资源消耗大。尽管现有的蒸馏方法已显示出在图像领域实现一步生成的潜力,但它们仍存在显著的质量退化问题。在本研究中,我们提出了一种在扩散预训练后针对真实数据…...
重回C语言之老兵重装上阵(十六)C语言可变参数
C语言可变参数 在C语言中,标准库提供了一些函数允许接收可变数量的参数。最典型的例子就是 printf 和 scanf,它们能够处理不确定数量的参数。为了实现这一功能,C语言提供了可变参数函数的概念。 1. 可变参数函数的概念 可变参数函数是指函数…...
深拷贝、浅拷贝、移动语义
C 中的拷贝方式 1. 深拷贝(Deep Copy) 定义 深拷贝会复制对象的全部内容,包括对象中动态分配的资源。新对象与原对象完全独立,任何对新对象的修改都不会影响原对象。 实现 通常通过显式的拷贝构造函数或拷贝赋值运算符&#…...
双向链表在系统调度、游戏、文本编辑及组态方面的应用
在编程的奇妙世界里,数据结构就像是一把把神奇的钥匙(前面我们介绍过单向链表的基础了,这里我们更进一步),能帮我们打开解决各种问题的大门。今天,咱们就来聊聊其中一把特别的钥匙——双向链表。双向链表和…...
实践网络安全:常见威胁与应对策略详解
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 引言 在数字化转型的浪潮中,网络安全的重要性已达到前所未有的高度。无论是个人用户、企业,还是政府机构…...
关于2024年
关于2024年 十分钟前我从床上爬起来,坐在电脑面前先后听了《黄金时代》——声音碎片和《Song F》——达达两首歌,我觉得躺着有些无聊,又或者除夕夜的晚上躺着让我觉得有些不适,我觉得自己应该爬起来,爬起来记录一下我…...
Hive:Hive Shell技巧
在终端命令窗口不能直接执行select,creat等HQL命令,需要先进入hive之后才能执行,比较麻烦,但是如果使用Hive Shell就可以直接执行 在终端只执行一次Hive命令 -e 参数, "execute"(执行),使用-e参数后会在执行完Hive的命令后退出Hive 使用场景:…...
Markdown Viewer 浏览器, vscode
使用VS Code插件打造完美的MarkDown编辑器(插件安装、插件配置、markdown语法)_vscode markdown-CSDN博客 右键 .md 文件,选择打开 方式 (安装一些markdown的插件) vscode如何预览markdown文件 | Fromidea GitCode - 全球开发者…...
快速分析LabVIEW主要特征进行判断
在LabVIEW中,快速分析程序特征进行判断是提升开发效率和减少调试时间的重要技巧。本文将介绍如何高效地识别和分析程序的关键特征,从而帮助开发者在编写和优化程序时做出及时的判断,避免不必要的错误。 数据流和并行性分析 LabVIEW的图形…...
【Super Tilemap Editor使用详解】(十五):从 TMX 文件导入地图(Importing from TMX files)
Super Tilemap Editor 支持从 TMX 文件(Tiled Map Editor 的文件格式)导入图块地图。通过导入 TMX 文件,你可以将 Tiled 中设计的地图快速转换为 Unity 中的图块地图,并自动创建图块地图组(Tilemap Group)。以下是详细的导入步骤和准备工作。 一、导入前的准备工作 在导…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
