c++继承(下)
c++继承(下)
- (1)继承与友元
- (2)继承与静态成员
- (3)多继承及其菱形继承问题
- 3.1 继承模型
- 3.2 虚继承
- 3.3 多继承中指针偏移问题
- (4)继承和组合
- (9)继承的总结
(1)继承与友元
友元关系不能继承,也就是说基类友元不能访问派⽣类私有和保护成员 。
class student;//前置声明class person
{
public:friend void func(person a,student b);//这里使用了student这个类,编译器只支持向下查找,必须前置声明void identify(){}
private:int _age;string _name = "zhangsan";
};class student:public person
{
public:friend void func(person a, student b);void study(){}private:int _stuid = 111;
};void func(person a,student b)
{cout << a._name << ' ' << b._stuid << endl;
}
int main()
{person aa;student bb;func(aa,bb);return 0;
}
要想让两个类都可以使用func函数,这里的解决办法是同时声明友元即可。
(2)继承与静态成员
基类定义了static静态成员,则整个继承体系⾥⾯只有⼀个这样的成员。⽆论派⽣出多少个派⽣类,都只有⼀个static成员实例。
class person
{
public:static int _count;void identify(){}
private:int _age;string _name = "zhangsan";
};int person::_count = 1;class student:public person
{
public:void study(){}private:int _stuid = 111;
};int main()
{person aa;student bb;person::_count++;cout << aa._count << endl;cout << bb._count << endl;cout << &aa._count << endl;cout << &bb._count << endl;return 0;
}
这份代码的运行结果:
我们可以看到count的地址没有发生变化,所以count只存在一份
(3)多继承及其菱形继承问题
3.1 继承模型
单继承:⼀个派⽣类只有⼀个直接基类时称这个继承关系为单继承
多继承:⼀个派⽣类有两个或以上直接基类时称这个继承关系为多继承,多继承对象在内存中的模型是,先继承的基类在前⾯,后⾯继承的基类在后⾯,派⽣类成员在放到最后⾯。
菱形继承:菱形继承是多继承的⼀种特殊情况。菱形继承的问题,从下⾯的对象成员模型构造,可以看出菱形继承有数据冗余和⼆义性的问题,在Assistant的对象中Person成员会有两份。⽀持多继承就⼀定会有菱形继承,像Java就直接不⽀持多继承,规避掉了这⾥的问题,所以实践中我们也是不建议设计出菱形继承这样的模型的。
单继承:
多继承:
菱形继承:
class person
{
public:static int _count;void identify(){}string _name = "zhangsan";
private:int _age;
};class student:public person
{
public:void study(){}
private:int _stuid = 111;//学号
};class teacher:public person
{
public:void teach(){}
private:string teaid;//教师编号
};//老师助理,这里的意思是教师助理既作为教授的学生,又作为学校里的老师
class assistant:public student,public teacher
{};//这里就是一个菱形继承
int main()
{assistant a;//a._name = "tsy";//这里具有二义性a.student::_name = "张三";a.teacher::_name = "李四";//这样指定是可以的//并且person在a里是有两份的,数据冗余不能解决//并且这里是有两个名字的,一个作为学生,一个作为老师,这样是不太好的,person里的名字应该是类似于身份证上的名字,我们最好不好去更改return 0;
}
3.2 虚继承
//这里引入了virtual,它被使用于产生数据冗余的地方,例如person会在student与teacher里各存一份,这里会产生数据冗余
class person
{
public:static int _count;void identify(){}string _name = "zhangsan";
private:int _age;
};class student :virtual public person
{
public:void study(){}
private:int _stuid = 111;//学号
};class teacher :virtual public person
{
public:void teach(){}
private:string teaid;//教师编号
};//老师助理,这里的意思是教师助理既作为教授的学生,又作为学校里的老师
class assistant :public student, public teacher
{};int main()
{assistant a;a._name = "tsy";//这里就可以使用了//这里给定的name就类似于身份证上的名字return 0;
}
virtual使用于产生数据冗余的地方,并且不可能单独出现
3.3 多继承中指针偏移问题
class Base1
{
public: int _b1;
};
class Base2
{
public: int _b2;
};
class Derive : public Base1, public Base2
{
public: int _d;
};int main()
{Derive d;Base1* p1 = &d;Base2* p2 = &d;Derive* p3 = &d;return 0;
}
//A:p1 == p2 == p3 B:p1 < p2 < p3 C:p1 == p3 != p2 D:p1 != p2 != p3
所以答案选择 C
(4)继承和组合
• public继承是⼀种is-a的关系。也就是说每个派⽣类对象都是⼀个基类对象。
• 组合是⼀种has-a的关系。假设B组合了A,每个B对象中都有⼀个A对象。
• 继承允许你根据基类的实现来定义派⽣类的实现。这种通过⽣成派⽣类的复⽤通常被称为⽩箱复⽤(white-box reuse)。术语“⽩箱”是相对可视性⽽⾔:在继承⽅式中,基类的内部细节对派⽣类可⻅ 。继承⼀定程度破坏了基类的封装,基类的改变,对派⽣类有很⼤的影响。派⽣类和基类间的依赖关系很强,耦合度⾼。
• 对象组合是类继承之外的另⼀种复⽤选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接⼝。这种复⽤⻛格被称为⿊箱复⽤(black-box reuse),因为对象的内部细节是不可⻅的。对象只以“⿊箱”的形式出现。 组合类之间没有很强的依赖关系,耦合度低。优先使⽤对象组合有助于你保持每个类被封装。
• 优先使⽤组合,⽽不是继承。实际尽量多去⽤组合,组合的耦合度低,代码维护性好。不过也不太那么绝对,类之间的关系就适合继承(is-a)那就⽤继承,另外要实现多态,也必须要继承。类之间的关系既适合⽤继承(is-a)也适合组合(has-a),就⽤组合。
// Tire(轮胎)和Car(⻋)更符合has-a的关系
class Tire {
protected:string _brand = "Michelin"; // 品牌size_t _size = 17;// 尺⼨
};
class Car {
protected:string _colour = "⽩⾊";// 颜⾊string _num = "陕ABIT00";// ⻋牌号Tire _t1;// 轮胎Tire _t2;// 轮胎Tire _t3;// 轮胎Tire _t4;// 轮胎
};
class BMW : public Car {
public:void Drive() { cout << "好开-操控" << endl; }
};
// Car和BMW/Benz更符合is-a的关系
class Benz : public Car {
public:void Drive() { cout << "好坐-舒适" << endl; }
};
template<class T>
class vector
{};
// stack和vector的关系,既符合is-a,也符合has-a
template<class T>
class stack : public vector<T>
{};
template<class T>
class stack
{
public:vector<T> _v;
};
int main()
{return 0;
}
(9)继承的总结
1、继承在生活中常见的只有公有继承,所以公有继承一定要弄明白。
2、派生类的默认成员函数与之前学的普通类的是一样的,如果我们需要显示的去写构造函数等等,需要将父类作为一个整体,去调用父类的构造等函数。
3、继承这块是先构造父类再构造子类,析构是先析构子类再析构父类
4、菱形继承目前阶段我们把握不住,并且用到的场景也可以通过其他方式解决,所以最好不要写菱形继承,但是学校可能会考,所以也是需要简单了解下的。
5、如果我们需要设计一个不能被继承的类,我们有两种方式:
(1)将基类构造函数变为私有
(2)final
class Base final
{
public:
void func5() { cout << "Base::func5" << endl; }
protected:
int a = 1;
private:
// C++98的⽅法
/*Base()
{}*/
};
class Derive :public Base
{
void func4() { cout << "Derive::func4" << endl; }
protected:
int b = 2;
};
int main()
{
Base b;
Derive d;
return 0;
}
这一点只做了解
相关文章:

c++继承(下)
c继承(下) (1)继承与友元(2)继承与静态成员(3)多继承及其菱形继承问题3.1 继承模型3.2 虚继承3.3 多继承中指针偏移问题 (4)继承和组合(9…...

数据结构 ——— 单链表oj题:反转链表
目录 题目要求 手搓一个简易链表 代码实现 题目要求 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表 手搓一个简易链表 代码演示: struct ListNode* n1 (struct ListNode*)malloc(sizeof(struct ListNode)); assert(n1);…...
前端项目npm install报错解决的解决办法
报错问题一: [rootspug-api spug_web]# npm install npm WARN deprecated xterm4.19.0: This package is now deprecated. Move to xterm/xterm instead. npm WARN deprecated workbox-google-analytics4.3.1: It is not compatible with newer versions of GA starting with v…...
vue双向绑定/小程序双向绑定区别
Vue双向绑定与小程序双向绑定在实现方式、语法差异以及功能特性上均存在显著区别。以下是对这两者的详细比较: 一、实现方式 Vue双向绑定 Vue的双向绑定主要通过其响应式数据系统实现。Vue使用Object.defineProperty()方法(或在Vue 3中使用Proxy对象&am…...
华为OD机试真题---字符串变换最小字符串
题目描述: 给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。 变换规则: 交换字符串中任意两个不同位置的字符。 输入描述: 一串小写字母组成的字符串s 输出描述: 按照要求进行变换得到的最小字符串 补…...

JAVA基础面试题汇总(持续更新)
1、精确运算场景使用浮点型运算问题 精确运算场景(如金融领域计算应计利息)计算数字,使用浮点型,由于精度丢失问题,会导致计算后的结果和预期不一致,使用Bigdecimal类型解决此问题,示例代码如下…...
设计模式-创建型-常用:单例模式、工厂模式、建造者模式
单例模式 概念 一个类只允许创建一个对象(或实例),那这个类就是单例类,这种设计模式就叫做单例模式。对于一些类,创建和销毁比较复杂,如果每次使用都创建一个对象会很耗费性能,因此可以把它设…...

【数据结构】【链表代码】随机链表的复制
/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/typedef struct Node Node; struct Node* copyRandomList(struct Node* head) {if(headNULL)return NULL;//1.拷贝结点,连接到原结点的后面Node…...

Linux 系统五种帮助命令的使用
Linux 系统五种帮助命令的使用 本文将介绍 Linux 系统中常用的帮助命令,包括 man、–help、whatis、apropos 和 info 命令。这些命令对于新手和有经验的用户来说,都是查找命令信息、理解命令功能的有力工具。 文章目录 Linux 系统五种帮助命令的使用一…...

Vueron引领未来出行:2026年ADAS激光雷达解决方案上市路线图深度剖析
Vueron ADAS激光雷达解决方案路线图分析:2026年上市展望 Vueron近期发布的ADAS激光雷达解决方案路线图,标志着该公司在自动驾驶技术领域迈出了重要一步。该路线图以2026年上市为目标,彰显了Vueron对未来市场趋势的精准把握和对技术创新的坚定…...

Java | Leetcode java题解之第458题可怜的小猪
题目: 题解: class Solution {public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {if (buckets 1) {return 0;}int[][] combinations new int[buckets 1][buckets 1];combinations[0][0] 1;int iterations minutesToTest /…...
怎么不改变视频大小的情况下,修改视频的时长
视频文件太大怎么变小?不影响画质的四种方法 怎么不改变视频大小的情况下,修改视频的时长 截取结尾的时间你可以使用 ffmpeg 来裁剪视频的结尾部分。假设你想去掉视频最后的3秒钟,可以先使用 ffmpeg 获取视频的总时长,然后通过指定一个新的…...

数据结构:AVL树
前言 学习了普通二叉树,发现普通二叉树作用不大,于是我们学习了搜索二叉树,给二叉树新增了搜索、排序、去重等特性, 但是,在极端情况下搜索二叉树会退化成单边树,搜索的时间复杂度达到了O(N),这…...

系统守护者:使用PyCharm与Python实现关键硬件状态的实时监控
目录 前言 系统准备 软件下载与安装 安装相关库 程序准备 主体程序 更改后的程序: 编写.NET程序 前言 在现代生活中,电脑作为核心工具,其性能和稳定性的维护至关重要。为确保电脑高效运行,我们不仅需关注软件优化…...

【工作流引擎集成】springboot+Vue+activiti+mysql带工作流集成系统,直接用于业务开发,流程设计,工作流审批,会签
前言 activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求。 一、项目形式 springbootvueactiviti集成了activiti在线编辑器,流行的前后端…...

SumatraPDF一打开就无响应怎么办?
结论:当前安装版不论32位还是64位都会出现问题。使用portable免安装版未发现相关问题。——sumatrapdf可以用于pdf, epub, mobi 等格式文件的浏览。 点击看相关问题和讨论...

棋牌灯控计时计费系统软件免费试用版怎么下载 佳易王计时收银管理系统操作教程
一、前言 【试用版软件下载,可以点击本文章最下方官网卡片】 棋牌灯控计时计费系统软件免费试用版怎么下载 佳易王计时收银管理系统操作教程 棋牌计时计费软件的应用也提升了顾客的服务体验,顾客可以清晰的看到自己的消费时间和费用。增加了消费的透明…...

Excel下拉菜单制作及选项修改
Excel下拉菜单 1、下拉菜单制作2、下拉菜单修改 下拉框(选项菜单)是十分常见的功能。Excel支持下拉框制作,通过预设选项进行菜单选择,可以避免手动输入错误和重复工作,提升数据输入的准确性和效率 1、下拉菜单制作 步…...
树莓派 mysql (兼容mariadb)登陆问题
树莓派 mysql (兼容mariadb)登陆问题 树莓派 MySQL 登陆问题 1 使用默认账号登陆 在首次登陆的情况下,系统默认为root用户授权 sudo su root  2. 使用root用户登…...

智能手表(Smart Watch)项目
文章目录 前言一、智能手表(Smart Watch)简介二、系统组成三、软件框架四、IAP_F411 App4.1 MDK工程结构4.2 设计思路 五、Smart Watch App5.1 MDK工程结构5.2 片上外设5.3 板载驱动BSP5.4 硬件访问机制-HWDataAccess5.4.1 LVGL仿真和MDK工程的互相移植5…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...