【C/C++ 17】继承
目录
一、继承的概念
二、基类和派生类对象赋值转换
三、继承的作用域
四、派生类的默认成员函数
五、继承与友元
六、继承与静态成员变量
七、菱形继承与虚拟继承
一、继承的概念
继承是指一个类可以通过继承获得另一个类的属性和方法,扩展自己的功能,提高了代码的复用性,增加了类与类之间的耦合性。
继承机制允许程序员在保持原有类特性的基础上进行扩展,增加功能,产生新的派生类。
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;class Person
{
public:void Print(){cout << "name: " << _name << ", " << "age: " << _age << endl;}private:string _name = "unknow";int _age = 0;
};class Student : public Person
{
private:string _stuID = "";
};class Teacher : public Person
{
private:string _jobID = "";
};int main()
{Student s;Teacher t;cout << typeid(s).name() << endl;cout << typeid(t).name() << endl;s.Print();t.Print();return 0;
}
| 类成员 / 继承方式 | public继承 | protect继承 | private继承 |
| 基类的public成员 | 派生类的public成员 | 派生类的protect成员 | 派生类的private成员 |
| 基类的protect成员 | 派生类的protect成员 | 派生类的protect成员 | 派生类的private成员 |
| 基类的private成员 | 派生类中不可见 | 派生类中不可见 | 派生类中不可见 |
由上表可见,类的继承遵循权限缩小原则,与函数传参类似。
二、基类和派生类对象赋值转换

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;class Person
{
protected:string _name; // 姓名string _sex; // 性别int _age; // 年龄
};class Student : public Person
{
public:int _No; // 学号
};void Test()
{Student sobj;// 1.子类对象可以赋值给父类对象/指针/引用Person pobj = sobj;Person* pp = &sobj;Person& rp = sobj;//2.基类对象不能赋值给派生类对象sobj = pobj;// 3.基类的指针可以通过强制类型转换赋值给派生类的指针pp = &sobj;Student* ps1 = (Student*)pp; // 这种情况转换时可以的。ps1->_No = 10;pp = &pobj;Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问题ps2->_No = 10;
}
三、继承的作用域
在继承体系中基类和派生类都有独立的作用域,子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)。
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;// Student的_num和Person的_num构成隐藏关系,可以看出这样代码虽然能跑,但是非常容易混淆
class Person
{
protected:string _name = "小李子"; // 姓名int _num = 111; // 身份证号
};class Student : public Person
{
public:void Print(){cout << " 姓名:" << _name << endl;cout << " 身份证号:" << Person::_num << endl;cout << " 学号:" << _num << endl;}protected:int _num = 999; // 学号
};int main()
{Student s1;s1.Print();
};
四、派生类的默认成员函数
派生类对象初始化先调用基类构造再调派生类构造。
派生类对象析构清理先调用派生类析构再调基类的析构
派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
派生类的operator=必须要调用基类的operator=完成基类的复制。
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;class Person
{
public:Person(const char* name = "peter"): _name(name){cout << "Person()" << endl;}Person(const Person& p): _name(p._name){cout << "Person(const Person& p)" << endl;}Person& operator=(const Person& p){cout << "Person operator=(const Person& p)" << endl;if (this != &p)_name = p._name;return *this;}~Person(){cout << "~Person()" << endl;}protected:string _name; // 姓名
};class Student : public Person
{
public:Student(const char* name, int num): Person(name), _num(num){cout << "Student()" << endl;}Student(const Student& s): Person(s), _num(s._num){cout << "Student(const Student& s)" << endl;}Student& operator = (const Student& s){cout << "Student& operator= (const Student& s)" << endl;if (this != &s){Person::operator =(s);_num = s._num;}return *this;}~Student(){cout << "~Student()" << endl;}protected:int _num; //学号
};int main()
{Student s1("jack", 18);Student s2(s1);Student s3("rose", 17);s1 = s3;
}/*
Person()
Student()
Person(const Person& p)
Student(const Student& s)
Person()
Student()
Student& operator= (const Student& s)
Person operator=(const Person& p)
~Student()
~Person()
~Student()
~Person()
~Student()
~Person()
*/
五、继承与友元
友元函数定义在类外部,可以访问类的私有成员和保护成员。
友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;#define _CRT_SECURE_NO_WARNINGS 1class Student;class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name; // 姓名
};class Student : public Person
{
protected:int _stuNum; // 学号
};void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._stuNum << endl; // 无法访问
}void main()
{Person p;Student s;Display(p, s);
}
六、继承与静态成员变量
基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;#define _CRT_SECURE_NO_WARNINGS 1class Person
{
public:Person() { ++_count; }
protected:string _name; // 姓名
public:static int _count; // 统计人的个数。
};// 静态成员在类外部赋值
int Person::_count = 0;class Student : public Person
{
protected:int _stuNum; // 学号
};class Graduate : public Student
{
protected:string _seminarCourse; // 研究科目
};void main()
{Student s1;Student s2;Student s3;Graduate s4;cout << " 人数 :" << Person::_count << endl;Student::_count = 0;cout << " 人数 :" << Person::_count << endl;
}
七、菱形继承与虚拟继承
菱形继承是多继承的一种特殊情况,但是菱形继承有数据冗余和二义性的问题。

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;#define _CRT_SECURE_NO_WARNINGS 1
class Person
{
public:string _name; // 姓名
};class Student : public Person
{
protected:int _num; //学号
};class Teacher : public Person{
protected:int _id; // 职工编号
};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};void main()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter"; // 报错,Assisitant::_name 不明确// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}
虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;#define _CRT_SECURE_NO_WARNINGS 1
class Person
{
public:string _name; // 姓名
};class Student : virtual public Person
{
protected:int _num; //学号
};class Teacher : virtual public Person{
protected:int _id; // 职工编号
};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};void main()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter"; // 报错,Assisitant::_name 不明确// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

虚继承会维护一张虚基表,每个虚成员函数的类都指向虚基表的指针,通过虚基表中存储的偏移量找到公共父类的成员变量。
相关文章:
【C/C++ 17】继承
目录 一、继承的概念 二、基类和派生类对象赋值转换 三、继承的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员变量 七、菱形继承与虚拟继承 一、继承的概念 继承是指一个类可以通过继承获得另一个类的属性和方法,扩展自己的功能&…...
解决Linux Shell脚本错误:“/bin/bash^M: bad interpreter: No such file or directory”
在Linux系统中运行Shell脚本时,你可能会遇到一个常见的错误,错误信息如下: -bash: ./xxx.sh: /bin/bash^M: bad interpreter: No such file or directory这个错误通常是由于Shell脚本文件中存在不兼容的换行符引起的。在Windows系统中&#…...
idea创建spring项目
一、环境 window10 IDEA 2022.2.3 maven-3.8.6 二、创建spring项目 1、新建Maven项目 File -> New -> Project 然后如下图选中Maven Archetype,在Archetype,选中maven-archetype-webapp,点击Create 2、配置maven 默认是使用IDEA内…...
【UE 材质】扇形材质
目录 效果 步骤 (1)控制扇形的弧宽度 (2)控制扇形的角度 (3)完整节点 效果 步骤 (1)控制扇形的弧宽度 创建一个材质,混合模式设置为“Additive”,着色…...
【react native】ScrollView的触摸事件与TouchableWithoutFeedback的点击事件冲突
需求背景 使用 ScrollView 组件实现轮播图效果,该轮播图可以自动向右滑动。有下面两个需求: (1)希望用户左右点击的时候,视图可以向左/向右滚动; (2)希望用户触摸在屏幕的时候&am…...
鸿蒙内核框架
1 内核概述 内核简介 用户最常见到并与之交互的操作系统界面,其实只是操作系统最外面的一层。操作系统最重要的任务,包括管理硬件设备,分配系统资源等,我们称之为操作系统内在最重要的核心功能。而实现这些核心功能的操作系统模…...
幻兽帕鲁专用服务器,多人游戏(专用服务器)搭建
玩转幻兽帕鲁服务器,阿里云推出新手0基础一键部署幻兽帕鲁服务器教程,傻瓜式一键部署,3分钟即可成功创建一台Palworld专属服务器,成本仅需26元,阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…...
7000字详解Spring Boot项目集成RabbitMQ实战以及坑点分析
本文给大家介绍一下在 Spring Boot 项目中如何集成消息队列 RabbitMQ,包含对 RibbitMQ 的架构介绍、应用场景、坑点解析以及代码实战。 我将使用 waynboot-mall 项目作为代码讲解,项目地址:https://github.com/wayn111/waynboot-mall。本文大…...
AJAX-认识URL
定义 概念:URL就是统一资源定位符,简称网址,用于访问网络上的资源 组成 协议 http协议:超文本传输协议,规定浏览器和服务器之间传输数据的格式;规定了浏览器发送及服务器返回内容的格式 协议范围…...
国图公考:公务员面试资格复审需要准备什么?
参加国考面试的考生在资格审核阶段需要准备以下材料: 1、本人身份证、学生证或工作证复印件。 2、公共科目笔试准考证复印件。 3、考试报名登记表。 4、本(专)科、研究生各阶段学历、学位证书(应届毕业生没有可以暂时不提供)。 5、报名资料上填写的各类证书材料…...
爬虫实战--人民网
文章目录 前言发现宝藏 前言 为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们…...
【Arduino】LGT8F328 UNO R3编译上传
LGT8F328 UNO R3编译上传 示例代码 这是一段示例代码,将示例代码编译打包上传到LGT8F328 UNO R3开发板。 #include <Servo.h> Servo myservo; int pos 0; void setup() {// put your setup code here, to run once:Serial.begin(9600);Serial.println(&qu…...
Python进阶----在线翻译器(Python3的百度翻译爬虫)
目录 一、此处需要安装第三方库requests: 二、抓包分析及编写Python代码 1、打开百度翻译的官网进行抓包分析。 2、编写请求模块 3、输出我们想要的消息 三、所有代码如下: 一、此处需要安装第三方库requests: 在Pycharm平台终端或者命令提示符窗口中输入以下代…...
ArcGISPro中Python相关命令总结
主要总结conda方面的相关命令 列出当前活动环境中的包 conda list 列出所有 conda 环境 conda env list 克隆环境 克隆以默认的 arcgispro-py3 环境为模版的 my_env 新环境。 conda create --clone arcgispro-py3 --name my_env --pinned 激活环境 activate my_env p…...
2024年混合云:趋势和预测
混合云环境对于 DevOps 团队变得越来越重要,主要是因为它们能够弥合公共云资源的快速部署与私有云基础设施的安全和控制之间的差距。这种环境的混合为 DevOps 团队提供了灵活性和可扩展性,这对于大型企业中的持续集成和持续部署 (CI/CD) 至关重要。 在混…...
c++入门学习④——对象的初始化和清理
目录 对象的初始化和清理: why? 如何进行初始化和清理呢? 使用构造函数和析构函数编辑 构造函数语法: 析构函数语法: 构造函数的分类: 两种分类方式: 三种调用方法: 括号法(默认构造函数调用&…...
Java-spring注解的作用
1.Qualifier:通常与Autowired搭配使用,通过指定具体的beanName来注入相应的bean 当容器中有多个类型相同的Bean时,可以使用Qualifier注解来指定需要注入的Bean。Qualifier注解可以用于字段、方法参数、构造函数参数等位置 Service public cl…...
Allegro如何把Symbols,shapes,vias,Clines,Cline segs等多种元素一起移动
Allegro如何把Symbols,shapes,vias,Clines,Cline segs等多种元素一起移动 在用Allegro进行PCB设计时,有时候需要同时移动某个区域的所有元素,如:Symbols,shapes,vias,Clines,Cline segs等元素。那么如何操作呢? 首先就是把Symbols,shapes,vias,Clines,Cline …...
【力扣】罗马数字转整数,哈希集合+模拟
罗马数字转整数原题地址 方法一:模拟 罗马数字是字符串,其中每个字符都对应一个整数值,为了方便查找,可以预先把这种对应关系存储到哈希表中。 遍历字符串,对于每个字符, 如果该字符不是最右边的字符&a…...
从长网址到短链接:探索网址缩短的神奇世界
欢迎来到我的博客,代码的世界里,每一行都是一个故事 从长网址到短链接:探索网址缩短的神奇世界 前言网址缩短的原理和历史网址缩短的应用场景网址缩短的安全风险网址缩短的未来趋势 前言 你是否曾经在浏览网页或社交媒体时遇到过一串看起来像…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
