c++ 重写 多态
1 重写(继承后(拼接基类后))
1.1 非虚函数 同名成员函数 (各自有一个xFunction() 内存 )
#include <iostream>
#include <String>
class BaseClass {
public:void xFunction() {std::cout << "BaseClass::xFunction()\n"; }
};class Subclass1 : public BaseClass {
public:void xFunction() {std::cout << "Subclass1::xFunction()\n";}
};int main() {Subclass1 subclass1;subclass1.xFunction();return 0;
}
输出:
Subclass1::xFunction()
基类对象内存布局:
+-------------+
| 其他成员变量 |
+-------------+
| xFunction() | -> 基类xFunction()函数的代码
+-------------+子类对象内存布局:
+-------------+
| 基类部分 | // 继承而来的基类的数据和方法
+-------------+
| 子类独有成员变量 |
+-------------+
| xFunction() | -> 子类xFunction()函数的代码
+-------------+
运行原则是:
- 子类对象可以直接访问继承而来的基类的数据和方法
- 当子类与基类存在同名函数时,根据就近原则,通过子类对象访问同名函数时,会调用子类自己的同名函数,即这里的Subclass1::xFunction()
- 如果要访问基类中被隐藏的同名函数,需要使用作用域解析运算符,如subclass1.BaseClass::xFunction()
所以在这个例子中,通过subclass1.xFunction()调用时,执行的就是子类中重写的xFunction()函数,输出"Subclass1::xFunction()"。
1.1.2 多次实例化subclass1对象 (就是多次创建应用这个类 开内存)
每个实例化对像的成员变量 内存是单独的
成员函数是多个此类实例对象 公用子类 基类的成员函数 用类:: 指明
成员函数代码区(共享):┌──────────────────────────────┐
│ 成员函数代码 │
│ (包括 BaseClass::xFunction) │
│ (包括 Subclass1::xFunction) │
└──────────────────────────────┘subclass1对象实例1:
┌──────────────────────────────┐
│ 成员变量 │
└──────────────────────────────┘subclass1对象实例2:
┌──────────────────────────────┐
│ 成员变量 │
└──────────────────────────────┘
1.2 虚函数virtual (只有一个xFunction()内存 在基类中, 重写就覆盖)
#include <iostream>
#include <String>
class BaseClass {
public:virtual void xFunction() {std::cout << "BaseClass::xFunction()\n"; }
};class Subclass1 : public BaseClass {
public:void xFunction() {std::cout << "Subclass1::xFunction()\n";}
};int main() {Subclass1 subclass1;subclass1.xFunction();return 0;
}
+------------------------+
| subclass1 |
+------------------------+
| vptr (指向虚函数表) |
+------------------------+
| |
| |
| |
| |
| |
| |
| |
| |
+------------------------++------------------------+
| BaseClass |
+------------------------+
| vtable (虚函数表) |
+------------------------+
| xFunction() |
+------------------------+就是subclass1存的是基类的xFunction()地址的地址?是的,您的理解是正确的。
subclass1中存的是指向基类中xFunction()这个成员函数的指针的地址。
所以它是一个二级指针。
2 多态(子类用基类模板创建/增加不同功能)
#include <iostream>class Operation {
public:virtual int calculate(int a, int b) = 0; // 纯虚函数,需要在子类中实现
};class Addition : public Operation {
public:int calculate(int a, int b) override {return a + b;}
};class Subtraction : public Operation {
public:int calculate(int a, int b) override {return a - b;}
};int main() {Operation* op1 = new Addition(); // 创建加法类对象,并将其指针赋值给基类指针Operation* op2 = new Subtraction(); // 创建减法类对象,并将其指针赋值给基类指针int result1 = op1->calculate(5, 3); // 调用加法类的calculate函数int result2 = op2->calculate(5, 3); // 调用减法类的calculate函数std::cout << "Result1: " << result1 << std::endl; // 输出加法计算结果std::cout << "Result2: " << result2 << std::endl; // 输出减法计算结果delete op1;delete op2;return 0;
}
Operation* op1 = new Addition(); 创建对象并开内存 并给基类一个初始地址,;
然后根据这个地址 基类分配各个成员的空间;
初始化完 基类Operation被改造有成员变量calculate();
子类 只有指向基类的地址 用于找到虚函数 成员变量;
+------------------------+
| Operation |
+------------------------+
| vtable (虚函数表) |
+------------------------+
| calculate() |
+------------------------++------------------------+
| Subtraction |
+------------------------+
| vptr (指向虚函数表) |
+------------------------+
3
3.1
Operation* op1 = new Addition();
3.2 & 取地址符号
Addition add; // 创建命名的 Addition 对象
Operation* op1 = &add; // 将对象的地址赋值给基类指针
是的,Operation* op1 = new Addition();这一行代码是在堆内存上动态分配了一个Addition对象。
具体来说:
new Addition() 在堆内存上创建了一个Addition对象,并返回该对象的地址
Operation* op1 定义了一个Operation类型的指针op1
= 将new Addition()返回的Addition对象的地址赋值给了指针op1
所以,op1指向了堆内存中动态分配的那个Addition对象。
而Addition add这行代码是在栈内存上创建了一个Addition类型的对象add。
两者的区别在于:
- new创建的是在堆内存上的对象
- 直接创建如Addition add的是在栈内存上的对象
堆内存对象的生命周期由程序员控制,栈内存对象的生命周期随着函数的结束而结束。
将Addition对象的地址赋值给Operation*类型的指针op1,实现了基类指针指向子类对象的效果,可以实现多态。这是面向对象编程中非常重要的概念。
相关文章:
c++ 重写 多态
1 重写(继承后(拼接基类后)) 1.1 非虚函数 同名成员函数 (各自有一个xFunction() 内存 ) #include <iostream> #include <String> class BaseClass { public:void xFunction() {std::cout << "BaseClass::xFunction()\n"; } };class Subclass1 …...
Git如何修改提交(commit)用户名称(user.name)和邮箱(user.email)
Git用户名 Git查看用户名 git config user.name修改Git提交用户名 修改全局Git用户名 git config --global user.name "xx" 修改当前服务/项目Git用户名 git config user.name "xx"如果出现以下错误,解决方案如下: 错误案例&am…...

知行之桥EDI系统HTTP签名验证
本文简要概述如何在知行之桥EDI系统中使用 HTTP 签名身份验证,并将使用 CyberSource 作为该集成的示例。 API 概述 首字母缩略词 API 代表“应用程序编程接口”。这听起来可能很复杂,但真正归结为 API 是一种允许两个不同实体相互通信的软件。自开发以…...

C++ DAY08 异常
概念 异常事件(如:除 0 溢出,数组下标越界,所要读取的文件不存在 , 空指针,内存不足 等等) 在 C 语言对错误的处理是两种方法: 一是使用整型的返回值标识错误; 二是使用 errn…...

vscode导入STM32CubeIDE工程文件夹未定义警告清除方法
0 前言 在我们使用vscode去编辑STM32CubeIDE的工程文件时,经常会出现一些类型未定义、头文件路径无效的问题,无法正常使用且非常影响观感。本文介绍如何设置vscode导入的STM32CubeIDE配置文件,解决这一问题。 1 vscode导入STM32CubeIDE工程…...

SparkSQL之Optimized LogicalPlan生成过程
经过Analyzer的处理,Unresolved LogicalPlan已经解析成为Analyzed LogicalPlan。Analyzed LogicalPlan中自底向上节点分别对应Relation、Subquery、Filter和Project算子。 Analyzed LogicalPlan基本上是根据Unresolved LogicalPlan一对一转换过来的,…...

Java中有几种基本数据类型以及转换方式【Java面经(1)】
问:Java中有几种基本数据类型呢?以及它们之间的转换方式。详细介绍下 总共有8种基本数据类型 byte 、short 、long 、float 、double 、boolean 、char 详细类型以及字节数: 基本数据类型的转换方式 自动类型转换:小–>大 byt…...
JVM虚拟机:JVM调优第一步,了解JVM常用命令行参数
本文重点 从本文课程开始,我们将用几篇文章来介绍JVM中常用的命令行的参数,这个非常重要,第一我们可以通过参数了解JVM的配置,第二我们可以通过参数完成对JVM的调参。以及后面的JVM的调优也需要用到这些参数,所以我们…...

CSS特效019:图标图片悬浮旋转一周
CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧,主要包含CSS布局,CSS特效,CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点,CSS特效主要是一些动画示例,CSS花边是描述了一些CSS…...
requests请求django接口跨域问题处理
参考: https://zhuanlan.zhihu.com/p/416978320 https://blog.csdn.net/SweetHeartHuaZai/article/details/130983179 使用httpx代替requests import httpxheaders {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.3…...
#Js篇:Promise
定义 Promise是异步操作解决方案,为异步操作提供统一接口。 Promise英文意思是“承诺”,表示其他手段无法改变。 返回 所有异步任务都返回一个Promise实例。 Promise实例有一个then方法,用于指定下一步的回调函数。 状态 异步操作未完…...

【数据库篇】关系模式的表示——(2)规范化
范式:范式是符合某一种级别的关系模式的集合 规范化:是指一个低一级的范式的关系模式,通过模式的分解转换为若干个高一级范式的关系模式的集合。 1NF 每个分量必须是不可分开的数据项,满足这个条件的关系模式就是1NF。 2NF 若…...

【C++那些事儿】类与对象(3)
君兮_的个人主页 即使走的再远,也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们,这里是君兮_,我之前看过一套书叫做《明朝那些事儿》,把本来枯燥的历史讲的生动有趣。而C作为一门接近底层的语言,无疑是抽象且难度颇…...

spark的算子
spark的算子 1.spark的单Value算子 Spark中的单Value算子是指对一个RDD中的每个元素进行操作,并返回一个新的RDD。下面详细介绍一些常用的单Value算子及其功能: map:逐条映射,将RDD中的每个元素通过指定的函数转换成另一个值&am…...
【科技素养】蓝桥杯STEMA 科技素养组模拟练习试卷7
1、一袋小球中有15个白球,3个红球和2个黑球。在随机从袋子中拿出至少()个小球后,才可以保证至少拿出了5个白球 A、5 B、10 C、8 D、15 答案:B 2、以下选项中,数值最接近十进制数114的是( &…...

MySQL MHA高可用架构搭建
快捷查看指令 ctrlf 进行搜索会直接定位到需要的知识点和命令讲解(如有不正确的地方欢迎各位小伙伴在评论区提意见,博主会及时修改) MySQL MHA高可用架构搭建 MHA(Master HA)是一款开源的 MySQL 的高可用程序…...
UE小计:顶部工具栏按钮添加下拉列表,大纲列表、资源管理窗口右键添加按键
下拉列表 void FYouPluginsModule::StartupModule() {FYouToolStyle::Initialize();FYouToolStyle::ReloadTextures();FYouToolCommands::Register();PluginCommands MakeShareable(new FUICommandList);PluginCommands->MapAction(FYouToolCommands::Get().PackByCloudAc…...

git stash 用法总结
目录 1,介绍场景1:场景2: 2,常用命令2.1,基础2.2,进阶1,存储时指定备注2,通过索引来操作指定的存储3,修改存储规则 2.3,查看 stash 修改的具体内容 1…...

Linux操作系统之apt常用命令记录
文章目录 apt 命令apt 语法apt 常用命令列出所有可更新的软件清单命令升级软件包列出可更新的软件包及版本信息升级软件包,升级前先删除需要更新软件包安装指定的软件命令:安装多个软件包:更新指定的软件命令显示软件包具体信息,例如…...

TCP 重传、滑动窗口、流量控制、拥塞控制的剖析
TCP 是一个可靠传输的协议,那它是如何保证可靠的呢? 为了实现可靠性传输,需要考虑很多事情,例如数据的破坏、丢包、重复以及分片顺序混乱等问题。如不能解决这些问题,也就无从谈起可靠传输。 那么,TCP 是…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...