cpp中的继承
一、继承概念
在cpp中,封装、继承、多态是面向对象的三大特性。这里的继承就是允许已经存在的类(也就是基类)的基础上创建新类(派生类或者子类),从而实现代码的复用。
如上图所示,Person是基类,Stu与Tea是派生类,Stu与Tea分别继承了基类中的对象,同时也有自己的类对象。
1.1派生类对基类的修改
派生类对象可以赋值给基类对象、基类指针、基类引用,这里的赋值只是把派生类中原本继承于父类的类对象赋值回去,对于派生类对象自己的类对象不会赋值。但是基类对象不能赋值给派生类对象。
如上图,派生类只能将基类中原有的(或者说继承过来的)_name和_gender赋值给父类,其余的无法赋值,如果是引用或指针,也是将派生类中基类对应的对象引用给或地址传给基类,基类修改时,子类也会受影响。
如上图,代码验证。注意,以上代码是在public继承时才会生效,如果换成protected时代码就会报错,protected继承下来的父类对象就是protected而非public,不支持修改的,private继承同理。
1.2父子类类成员变量、函数重名
当父类类成员变量名与子类成员变量名冲突时,默认时优先使用子类的。其实子列中也继承了父类中的重名变量,只不过将其隐藏,可以通过指定类成员名::变量名的方式访问。
再提一点,如果子类中没有实现Print函数而是依靠父类中的Print函数,那么打印结果会是这样的,如下图。
这是因为返回给父类的是一个Person类型的this指针,解引用访问的就是Person类中的_val.
当存在同名的函数名时,子类会调用自身的函数,也可以通过类名指定的方式进行访问。
如上图,这里A::func与B::func关系是隐藏,注意与函数重载区分(函数重载条件是同一作用域内函数名相同,参数列表不同构成重载)。
1.3派生类的默认成员函数
#include <iostream> using namespace std; class Person { public://构造函数Person() :_name("张三") {cout << "Person()" << endl;}//析构函数~Person() {cout << "~Person()" << endl;}//拷贝构造Person(const Person& p1):_name(p1._name) {cout << "Person(copy construct)" << endl;}Person& operator=(const Person& p1) {cout << "operator=" << endl;if (this != &p1) {this->_name = p1._name;}return *this;}public:string _name; };class Son :public Person { public:Son(const char* name = "", const string id = "111"):_id(id){}void display() {cout << _name << " " << _id << endl;} private:string _id; };int main() {Son s1;s1.display();return 0; }子类继承父类时会调用父类的构造函数来初始化继承过来的成员,然后子类在初始化自己的成员,同理对于析构、拷贝构造、赋值重载等都是同理。
如上图,s1会对继承的成员调用其对应的类的构造函数,当然,这也是我没有自定义时会调用父类的构造函数对其进行构造。
那么如何进行自定义构造_name呢?
如上图所示,通过son的构造函数对s1进行实例化构造,但是对于从父类继承下来的_name进行自定义时需要注意的是,在初始化_name时我们不能通过直接初始化的方式进行构造(如38行代码,这是错误的),而是通过父类的构造函数对父类成员进行初始化。在上图中也可以看见代码在初始化列表时(代码36行)就会调用父类的构造函数对_name进行初始化。
当然,也可以不自定义,此时_name就调用父类默认的构造函数对其进行初始化(前提是父类要有全缺省的构造函数,不然代码就会报错)。也可以使用初始化匿名对象的方式完成。
如上图所示,同时也要在父类中定义相对应的构造函数类型。
实现子类对象的拷贝构造函数
如上图,在实现子类的拷贝构造函数时,可以用子类类型的s来实例化Person,(这就是切片:父类可以提取子类中从父类继承来的_name进行初始化通过参数来初始化基类成员)
实现子类对象的赋值重载函数
如上图,实现子类对象的赋值重载函数时需要指明具体是哪一个重载函数,否则就会出现死循环,因为子类和父类出现同名函数时会优先调用子类的函数。代码第61行将Son类对象s进行切片,然后调用父类Person的重载函数将s中父类的部分切给Person完成赋值重载。
1.4继承与友元的关系
如上图所示,父类A的友元函数为display,子类B继承了父类A,此时友元函数只能访问子类的公开成员,对于受保护和私有的则无法访问。
1.5继承与静态成员
如上图,父类A中定义的静态成员变量在整个继承体系中都是存在的。
1.6菱形继承
如下图,A是B和C的父类,D又同时继承了B和C,此时D中含有基类成员_d和父类B(_b)和父类C(_c),同时B和C又同时含有A(_a),因此我们在访问_a时需要指定类域。
在上述图中可见,在开辟空间时,内存中64~68是父类B的空间,其中存放了B::_a和B::_b,对应的值就是1和3;而6C~70是父类C的空间,其中存放的就是C::_a和C::_C,对应的值就是2和4,最后一个位置就是D::_d。
如上图,整个44~54是类对象D的空间。
造成代码冗余与二义性问题
在上述代码中,子类D会同时存储了两份A的继承,分别是继承B和C的,这个就造成了代码冗余与内存消耗;其次当D访问A中成员时必须要指定具体哪个类中的(无法通过d._a方式访问)。解决方法就是虚拟继承。
如上图,通过虚拟继承的方法可以直接访问d._a,其实这里的B和C共享同一分A的继承,也就是说代码第91和92行对_a的修改是对同一个对象的修改(这一点在代码运行过程中可以看出)。
如上图所示,不难发现虽然_a是类中共享的一份区域,但是C和B区域与非虚拟继承相比又多出一块区域(如上图中绿色区域所示)。在分析内存时,0x0078FEAC指向的位置是0x00929bf4,0x0078FEC0指向的位置是0x00929c00,其内存图如下图所示
如上图所示,虽然0x00929bf4与0x00929c00指向的位置内容为空,但是其后一个位置的0000000c从十六进制转换为十进制刚好是12,其实这也就是C到_a的偏移量,这个表叫做虚基表,而只想虚机表的指针叫做虚机表指针。
相关文章:
cpp中的继承
一、继承概念 在cpp中,封装、继承、多态是面向对象的三大特性。这里的继承就是允许已经存在的类(也就是基类)的基础上创建新类(派生类或者子类),从而实现代码的复用。 如上图所示,Person是基类&…...
DeepSeek全栈接入指南:从零到生产环境的深度实践
第一章:DeepSeek技术体系全景解析 1.1 认知DeepSeek技术生态 DeepSeek作为新一代人工智能技术平台,构建了覆盖算法开发、模型训练、服务部署的全链路技术栈。其核心能力体现在: 1.1.1 多模态智能引擎 自然语言处理:支持文本生成(NLG)、语义理解(NLU)、情感分析等计算…...
CSS 真的会阻塞文档解析吗?
在网页开发领域,一个常见的疑问是 CSS 是否会阻塞文档解析。理解这一问题对于优化网页性能、提升用户体验至关重要。要深入解答这个问题,需要从浏览器渲染网页的原理说起。 浏览器渲染网页的基本流程 浏览器在接收到 HTML 文档后,会依次进行…...
大模型的UI自动化:Cline 使用Playwright MCP Server完成测试
大模型的UI自动化:Cline 使用Playwright MCP Server完成测试 MCP MCP(Model Context Protocol),是一个开发的协议,标准化了应用程序如何为大模型提供上下文。MCP提供了一个标准的为LLM提供数据、工具的方式,使用MCP会更容易的构建Agent或者是基于LLM的复杂工作流。 最近…...
碰撞检测 | 图解凸多边形分离轴定理(附ROS C++可视化)
目录 0 专栏介绍1 凸多边形碰撞检测2 多边形判凸算法3 分离轴定理(SAT)4 算法仿真与可视化4.1 核心算法4.2 仿真实验 0 专栏介绍 🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战,包括:曲线…...
Python 基本数据类型
目录 1. 字符串(String) 2. 列表(List) 3. 字典(Dictionary) 4. 集合(Set) 5. 数字(Number) 6. 布尔值(Boolean) 1. 字符串&…...
突破“第一崇拜“:五维心理重构之路
一、视频介绍 在这个崇尚"第一"的时代,我们如何找到自己的独特价值?本视频将带您踏上五维心理重构之旅,从诗意人生的角度探讨如何突破"圣人之下皆蝼蚁"的局限。我们将穿越人生的不同阶段,从青春的意气风发到…...
KubeKey一键安装部署k8s集群和KubeSphere详细教程
目录 一、KubeKey简介 二、k8s集群KubeSphere安装 集群规划 硬件要求 Kubernetes支持版本 操作系统要求 SSH免密登录 配置集群时钟 所有节点安装依赖 安装docker DNS要求 存储要求 下载 KubeKey 验证KubeKey 配置集群文件 安装集群 验证命令 登录页面 一、Ku…...
UE5网络通信架构解析
文章目录 前言一、客户端-服务器架构(C/S Model)二、对等网络架构(P2P,非原生支持)三、混合架构(自定义扩展)四、UE5网络核心机制 前言 UE5的网络通信主要基于客户端-服务器(C/S&am…...
实验3 知识表示与推理
实验3 知识表示与推理 一、实验目的 (1)掌握知识和知识表示的基本概念,理解其在AI中的深刻含义与意义; (2)熟悉AI中常用的知识表示方法的优缺点及其应用场景; (3)掌握产…...
基于Springboot银行信用卡额度管理系统【附源码】
基于Springboot银行信用卡额度管理系统 效果如下: 系统登陆页面 用户个人中心页面 新增信用卡申请页面 评估审核页面 管理员主页面 评估审核页面 操作日志管理页面 消费页面 研究背景 随着金融行业的快速发展和信息技术的不断进步,信用卡作为一种便捷…...
达梦数据库学习笔记@1
目录 达梦数据库学习笔记一、表空间管理(一)默认表空间(二)相关数据字典(三)表空间操作(四)临时表空间管理 二、重做日志管理(一)系统视图(二&…...
图像处理篇---图像处理中常见参数
文章目录 前言一、分贝(dB)的原理1.公式 二、峰值信噪比(PSNR, Peak Signal-to-Noise Ratio)1.用途2.公式3.示例 三、信噪比(SNR, Signal-to-Noise Ratio)1.用途2.公式3.示例 四、动态范围(Dyna…...
AI Agent实战:打造京东广告主的超级助手 | 京东零售技术实践
前言 自2022年末ChatGPT的问世,大语言模型(LLM)技术引发全球关注。在大模型技术落地的最佳实践中,智能体(Agent)架构显现出巨大潜力,成为业界的普遍共识,各大公司也纷纷启动Agent技…...
50周学习go语言:第1周 环境搭建
以下是为零基础学习者准备的详细第1周教程,包含环境搭建、工具配置和首个Go程序的完整操作指南: 一、Go语言环境安装(Windows/macOS/Linux通用) 1. 下载安装包 官网地址:https://go.dev/dl//根据系统选择对应版本&am…...
4. MySQL 逻辑架构说明
4. MySQL 逻辑架构说明 文章目录 4. MySQL 逻辑架构说明1. 逻辑架构剖析1.1 服务器处理客户端请求1.2 Connectors(连接器)1.3 第1层:连接层1.4 第2层:服务层1.5 第3层:引擎层1.6 存储层 2. SQL执行流程2.1 MySQL 中的 SQL 执行流程 2.2 MySQL…...
《AI与NLP:开启元宇宙社交互动新纪元》
在科技飞速发展的当下,元宇宙正从概念逐步走向现实,成为人们关注的焦点。而在元宇宙诸多令人瞩目的特性中,社交互动体验是其核心魅力之一。人工智能(AI)与自然语言处理(NLP)技术的迅猛发展&…...
面对STM32的庞大体系,如何避免迷失在细节中?
我第一次接触STM32时,我以为抱着开发板就是拥抱未来,实际上一开机就喜提四大耳光,看到卖家演示的MP3播放、TFT彩屏、网口通信好炫酷,忍不住买回来掌握这些神技,到最后发现最实用的还是开发板的关机键和复位键。 看视频…...
ragflow-RAPTOR到底是什么?请通俗的解释!
RAPTOR有两种不同的含义,具体取决于上下文: RAPTOR作为一种信息检索技术 RAPTOR是一种基于树状结构的信息检索系统,全称为“Recursive Abstractive Processing for Tree-Organized Retrieval”(递归抽象处理树组织检索)…...
Linux系统移植之Uboot启动流程
Linux系统移植之Uboot启动流程 一,Uboot启动流程1.Uboot的两阶段1.1.第一阶段1.11.硬件初始化1.12.复制 U-Boot 到 RAM1.13.跳转到第二阶段 1.2.第二阶段1.21.C 语言环境初始化1.22. 硬件设备初始化1.23. 加载环境变量1.24. 显示启动信息1.25. 等待用户输入…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
6.9本日总结
一、英语 复习默写list11list18,订正07年第3篇阅读 二、数学 学习线代第一讲,写15讲课后题 三、408 学习计组第二章,写计组习题 四、总结 明天结束线代第一章和计组第二章 五、明日计划 英语:复习l默写sit12list17&#…...























