C++ 继承(2)
Hello!!大家早上中午晚上好!!今天收尾继承剩余部分内容!!
一、友元不能继承
基类的友元函数不能被子类继承,也就是基类的友元函数访问不了子类的私有或保护成员!
1.1解决方法在子类再声明一次友元
//基类友元不能访问子类私有和保护成员
class B;
class A
{
public:friend void Print(const B& b);int _a=0;
};
class B:public A
{//friend void Print(const B& b);const char* _ch = "你好!!";
};
void Print(const B& b)
{cout << b._ch << endl;//报错
}
int main()
{A a;B b;Print(b);return 0;
}
编译报错:

解决办法:在子类再声明一次友元函数
代码更改:
class B:public A
{friend void Print(const B& b);//子类声明友元const char* _ch = "你好!!";
};
再运行:

二、基类的静态成员
2.1在继承体系中,基类的静态成员,有且只有一份实例,无论派生出多少个子类;
class A
{
public:A() {++cout;}static int cout;
};
int A::cout = 0;
class B:public A
{
};
class C :public B
{};
int main()
{A a1;B b1;B b2;B B3;C c1;cout << A::cout << endl;cout << B::cout << endl;cout << C::cout << endl;B::cout = 0;cout << A::cout << endl;cout << B::cout << endl;cout << C::cout << endl;return 0;
}
2.2运行:

三、多继承
3.1首先理解单继承
什么是单继承?
当子类只有一个直接父类的时候属于单继承:

3.2再来理解多继承
什么是多继承?
当子类有两个或以上的直接父类的时候属于多继承:

3.3多继承衍生出的菱形继承
什么是菱形继承?
如图:
3.4菱形继承衍生出数据冗余和二义性问题
写一个简单的菱形继承:
class Person
{
public:string _name = "张三";
};
class Student :public Person
{
public:int _id=12345;//学号
};
class Teacher :public Person
{
public:int _number=112233;//职工编号
};
class Scientist :public Student, public Teacher
{
public:string _subject = "物理";
};
int main()
{Scientist s1;cout << s1._name << endl;//报错return 0;
}
图解:

编译报错:

因为此时Scientist里有一个两个类对象,这两个类对象里都存在一个_name,编译器就不知道访问哪个,这就是菱形继承产生二义性的问题;
虽然你可以用类域访问符访问,但数据冗余问题依然存在,Scientist里面始终存在两个一样的成员变量!
用类域访问

四、菱形虚拟继承
4.1使用虚拟继承解决菱形继承存在数据冗余和二义性的问题
方法:在腰部位置添加virtual关键字(注意:除了菱形继承不要在其他位置使用虚拟继承)
代码更改:
class Student :virtual public Person
{
public:int _id=12345;//学号
};
class Teacher :virtual public Person
{
public:int _number=112233;//职工编号
};
更改完后不需要加类域访问符编译也不会报错;
4.2虚拟继承的底层实现
为了方便查看,重新定义简化版的菱形虚拟继承,走内存窗口查看实现原理:
class A
{
public:int a;
};
class B :virtual public A
{
public:int b;
};
class C :virtual public A
{
public:int c;
};
class D :public B, public C
{
public:int d;
};
int main()
{//给每个成员变量赋值方便查看D d;d.B::a = 1;d.C::a = 2;d.b = 3;d.c = 4;d.d = 5;return 0;
}
F10走起:

分析:

由此可以看出虚拟菱形继承的实现原理是:
①基类成员只生成一份放到最下面(解决了数据冗余);
②每存在一个派生类 -> 派生类对应部分首地址存放一个虚表指针 -> 这个指针指向其对应的虚基表 -> 虚基表里存放的是相对于指针当前位置A类成员的偏移量 -> 每个派生类通过其内的指针就能访问到A类成员 ,从而(解决了数据二义性)的问题!
4.3总结
回观整个问题产生及解决过程:
继承衍生出多继承 -> 多继承衍生出菱形继承 -> 菱形继承衍生出数据冗余以及二义性的问题 -> 解决办法虚拟继承 -> 虚拟继承实现原理 -> 利用虚基表指针 -> 虚基表存放偏移量 -> 通过指针访问解决问题!!
因此解决菱形继承问题是非常复杂的过程,在我们以后的程序设计尽量避免设计成菱形继承!!!
五、继承与组合的选择
5.1什么是组合?
组合就是在类里面直接使用定义好的类,不需要继承!
简单的组合使用:
class Tire//轮胎类
{
public:int _id = 011;//轮胎型号int _size = 10;//轮胎大小
};
class Car //车类
{
public:string _Cartype = "大巴车";//车类型Tire _t;//类里用轮胎类定义,不需要继承
};
简单的继承使用:
class Tire//轮胎类
{
public:int _id = 011;//轮胎型号int _size = 10;//轮胎大小
};
class Car //车类
{
public:string _Cartype = "大巴车";//车类型Tire _t;//类里用轮胎类定义,不需要继承
};class Animal //动物类
{
public:char _Ability[10] = "五颗星";//运动能力string _structure = "多细胞有机体";//细胞结构
};
class Dog :public Animal//狗类
{
public:char _name[10] = "哈士奇";void Dance(){cout << "汪汪汪!!我会跳舞!!动次打次!!!" << endl;}
};
int main()
{Dog hashiqi;cout << "名字:" << hashiqi._name << endl;cout << "运动能力:" << hashiqi._Ability << endl;cout << "细胞结构:" << hashiqi._structure << endl;hashiqi.Dance();return 0;
}
运行:

总结:
①当关系为is - a 时用继承,例:哈士奇是狗,玫瑰是花,杨柳是树等等;
②当关系为has - a时用组合,例:车里有轮胎(而不能说车是轮胎),人有嘴巴(而不能说人是嘴巴),瓶子里有水(而不能说瓶子是水)等等;
5.2组合与继承的优劣
1、组合耦合度低,继承耦合度高,优先用组合;
2、继承一定程度破坏了基类的封装,基类的改变对派生类有很大的影响;派生类和基类的依赖关系很强!
好了,今天就复习到这里!!如果您觉得有所收获请点赞收藏+关注哦!!谢谢!!!
如果您有更好的意见欢迎评论区留言!!
咱下期见!!!
相关文章:
C++ 继承(2)
Hello!!大家早上中午晚上好!!今天收尾继承剩余部分内容!! 一、友元不能继承 基类的友元函数不能被子类继承,也就是基类的友元函数访问不了子类的私有或保护成员! 1.1解决方法在子…...
解决:Word 保存文档失败,重启电脑后,Word 在试图打开文件时遇到错误
杀千刀的微软,设计的 Word 是个几把,用 LaTex 写完公式,然后保存,卡的飞起 我看文档卡了很久,就关闭文档,然后 TMD 脑抽了重启电脑 重启之后,文档打不开了,显示 杀千刀的ÿ…...
【docker简化部署有状态prometheus+grafana】
文章目录 第一步 下载依赖第二步 选择一个有权限的文件夹新建配置文件prometheus.ymldocker中运行命令存储数据启动prometheus 第三步 启动grafana 第一步 下载依赖 docker pull grafana/grafana:latest docker pull prom/prometheus:latest第二步 选择一个有权限的文件夹 例…...
Java- “equals“和“==“
"equals" 用于比较是否相等 equals() 是Object类下的一个方法,而非运算符。所以只有引用数据类型才可以使用 equals()方法,基本数据类型不能使用 equals()方法; object类下的equals()源码 public boolean equals(Object obj) {return (this…...
使用 potrace.js实现图像矢量化教程
在现代Web开发中,将位图转换为矢量图形的需求日益增加。矢量图形具有可缩放性、无损质量等优点,适用于多种应用场景,如图标设计、数据可视化和响应式网页设计。potrace.js 是一个基于浏览器的JavaScript库,它实现了著名的Potrace算…...
C++后端服务器开发技术栈有哪些?有哪些资源或开源库拿来用?
一、 C后台服务器开发是一个涉及多方面技术选择的复杂领域,特别是在高性能、高并发的场景下。以下是C后台服务器开发的一种常见技术路线,涵盖了从基础到高级的技术栈。 1. 基础技术栈 C标准库 C11/C14/C17/C20:使用现代C特性,如…...
基于DeepSeek与搜索引擎构建智能搜索摘要工具
基于DeepSeek与搜索引擎构建智能搜索摘要工具 1. 项目概述 本项目通过整合DuckDuckGo搜索引擎与DeepSeek大语言模型,实现了一个智能搜索摘要生成工具。系统可自动执行以下流程: 输入查询语句进行全网搜索获取并解析搜索结果调用AI模型生成结构化摘要输出带来源标注的专业级…...
基于Asp.net的零食购物商城网站
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
springboot的实体类字段校验的分组校验
分组校验(Group Validation)允许在不同的场景下对同一个实体类应用不同的校验规则。例如,在新增数据和更新数据时,可能需要对某些字段的校验规则进行调整。以下是分组校验的具体实现步骤: 一、定义分组接口 创建空的标…...
ESP8266UDP透传
1. 配置 WiFi 模式 ATCWMODE3 // softAPstation mode 响应 : OK 2. PC 连⼊入 ESP8266 softAP 就是连接wifi 3.查询ESP8266设备的IP地址 ATCIFSR 响应: CIFSR: APIP, "192.168.4.1" CIFSR: APMAC, "1a: fe: 34: a5:8d: c6" CIFSR: STAIP, "192.…...
UE5从入门到精通之如何创建自定义插件
前言 Unreal 的Plugins插件系统中有很多的插件供大家使用,包括官方的和第三方的,这些插件不仅能帮我我们实现特定功能,还能够提升我们的工作效率。 所以我们今天就来自己创建一个自定义插件,如果我们想实现什么特定的功能,我们也可以发布到商店供大家使用了。 创建插件 …...
基于python大数据的招聘数据可视化与推荐系统
博主介绍:资深开发工程师,从事互联网行业多年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有…...
olmOCR:高效精准的 PDF 文本提取工具
在日常的工作和学习中,是否经常被 PDF 文本提取问题困扰?例如: 想从学术论文 PDF 中提取关键信息,却发现传统 OCR 工具识别不准确或文本格式混乱?需要快速提取商务合同 PDF 中的条款内容,却因工具不给力而…...
Python asyncIO 面试题及参考答案 草
目录 如何正确定义一个协程函数?直接调用协程会引发什么问题? 使用 async def 定义的协程与普通函数执行流程有何本质区别? 解释 asyncio.run () 的作用及与手动管理事件循环的差异 为什么协程中必须使用 await 而非 yield 挂起操作? 写出通过 async for 实现异步迭代器…...
Spring Boot使用JDBC /JPA访问达梦数据库
Spring Boot 是一个广泛使用的 Java 框架,用于快速构建基于 Spring 的应用程序。对于达梦数据库(DMDB)的支持,Spring Boot 本身并没有直接内置对达梦数据库的集成,但你可以通过一些配置和依赖来支持达梦数据库。 以下…...
构建自己的AI客服【根据用户输入生成EL表达式】
要实现一个基于对话形式的AI客服系统,该系统能够提示用户输入必要的信息,并根据用户的输入生成相应的EL(Expression Language)表达式编排规则,您可以按照以下步骤进行设计和开发。本文将涵盖系统架构设计、关键技术选型…...
谈谈 HTTP 中的重定向,如何处理301和302重定向?
一、HTTP重定向的核心概念 (一)301 vs 302 的本质区别 301 永久重定向 表示资源已永久迁移到新地址,客户端和搜索引擎都会更新记录。语义示例:域名迁移、旧产品页面下线。 302 临时重定向 表示资源暂时不可用(如…...
【五.LangChain技术与应用】【31.LangChain ReAct Agent:反应式智能代理的实现】
一、ReAct Agent是啥?为什么说它比「普通AI」聪明? 想象一下,你让ChatGPT查快递物流,它可能直接编个假单号糊弄你。但换成ReAct Agent,它会先推理(Reasoning)需要调用哪个接口,再行动(Action)查询真实数据——这就是ReAct的核心:让AI学会「动脑子」再动手。 举个真…...
基于PyTorch的深度学习3——非标量反向传播
以下内容由大语言模型生成: 张量,边代表从输入到输出的操作。当我们对一个标量调用backward()函数时,PyTorch能够直接计算该标量关于参与运算的所有张量的梯度。这是因为导数的概念最开始是针对标量值定义的。 为什么需要传入gradient参数&…...
SpringCloud中使用服务名调用场景总结
一 API Gateway 在 Spring Cloud API Gateway 中,通过使用 lb:// 前缀可以实现基于服务名的负载均衡路由。以下是具体的配置和使用方法: 1. 配置服务注册与发现 确保你的服务已经注册到服务注册中心(如 Nacos 或 Eureka)。API …...
开发ai模型最佳的系统是Ubuntu还是linux?
在 AI/ML 开发中,Ubuntu 是更优选的 Linux 发行版,原因如下: 1. 开箱即用的 AI 工具链支持 Ubuntu 预装了主流的 AI 框架(如 TensorFlow、PyTorch)和依赖库,且通过 apt 包管理器可快速部署开发环境。 提…...
OpenText ETX 助力欧洲之翼航空公司远程工作升级
欧洲之翼航空公司,作为欧洲知名的低成本航空公司,拥有超过 130 架飞机,服务于约 60 个国家的 210 多个目的地,是欧洲第三大的点对点航空公司。面对 2020年 冠状病毒大流行的挑战,欧洲之翼航空公司迅速采取行动…...
计算机数据库三级刷题总结(博主89分已过,总结的内容分享)
计算机数据库三级刷题总结(博主89分已过,总结的内容分享) 文章目录 计算机数据库三级刷题总结(博主89分已过,总结的内容分享)一、 数据库设计阶段二、事务相关三、数据库设计顺序四、数据库三级模式与二层映…...
特征表示深度解析:颜色、纹理、形状与编码
第一部分:颜色与纹理特征(Part 1) 1. 颜色特征 颜色直方图(Color Histogram) 定义:统计图像中各颜色通道(R/G/B)的像素分布,形成直方图。 计算步骤: 将每个…...
LeetCode Hot100刷题——反转链表(迭代+递归)
206.反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例 3&#…...
MCU-缓存Cache与CPU中的主存SRAM
缓存(Cache)和主存(SRAM)均属于 SRAM,他们的核心区别: 通过 Cache 缓存 Flash 中的指令和数据,可避免 CPU 因等待数据而停滞。主存 SRAM 存储程序运行时的变量、堆栈、临时数据等。通常作为 …...
在Windows 11的WSL中安装Kali Linux
Kali Linux 是网络安全从业者和爱好者的首选工具集,但直接在物理机或虚拟机上运行可能占用较多资源。借助 Windows Subsystem for Linux (WSL),我们可以在Windows 11中原生运行Kali Linux,轻量且高效。本教程将手把手教你如何在WSL2中安装并配…...
Manus AI Agent 技术解读:架构、机制与竞品对比
目录 1. Manus 是什么? 1.1 研发背景 1.2 技术特点 1.3 工具调用能力 1.4 主要应用场景 2. Manus 一夜爆火的原因何在? 2.1 技术突破带来的震撼 2.2 完整交付的产品体验 2.3 生态与开源策略 3. Manus 与其他 AI Agent 的对比分析 3.1 技术架构…...
010---基于Verilog HDL的分频器设计
文章目录 摘要一、时序图二、程序设计2.1 rtl2.2 tb 三、仿真分析四、实用性 摘要 文章为学习记录。绘制时序图,编码。通过修改分频值参数,实现任意整数分频器设计。 一、时序图 二、程序设计 2.1 rtl module divider #(parameter DIV_VALUE 5) (…...
Python贝壳网二手小区数据爬取(2025年3月更)
文章目录 一、代码整体架构解析二、各部分代码详解1. main()主函数解析2. 会话初始化(伪装浏览器身份)3. 动态参数生成(反爬虫核心机制)4. 列表页抓取(获取小区列表)5. 列表页解析(提取小区信息…...
