当前位置: 首页 > news >正文

C++之继承<2>【详解】

C++之继承<2>【详解】

  • 1. 派生类的默认成员函数
    • 1.1 1. 构造成员函数
    • 1.2 拷贝复制
    • 1.3 构造函数和析构函数的执行顺序
  • 2. 继承和友元
  • 3. 继承与静态成员

1. 派生类的默认成员函数

1.1 1. 构造成员函数

  派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。

  无论是否显示的调用基类的构造成员函数,都会自动调用基类的默认成员函数:

#include <iostream>
using namespace std;
class Person
{
public:Person(const char* name = "peter"): _name(name){cout << "Person()" << endl;}string _name; 
};class Student : public Person
{
public:Student(const char* name, int num): _num(num){cout << "Student()" << endl;}
protected:int _num; 
};
int main()
{Student s1("jack", 18);return 0;
}

没有显示调用
显示调用后:
在这里插入图片描述

上述的后半段的意义是:如果基类没有默认的构造函数,那么是这样的:

	Person(const char* name = "peter"): _name(name){}

  可以进行传参来构造对象,如果你在派生类没有显示的调用它,那么不能进行进行传参来构造。

#include <iostream>
using namespace std;class Person
{
public:Person(const char* name = "peter"): _name(name){cout << "Person()" << endl;}string _name; 
};class Student : public Person
{
public:Student(const char* name, int num): _num(num){cout << "Student()" << endl;}
protected:int _num; 
};
int main()
{Student s1("jack", 18);	cout << s1._name; return 0;
}

在这里插入图片描述
上图可以看到,传入的参数是“jack”, 但是构造出来的对象属性是“peter”。
  至于必须在初始化列表显示的调用,是因为祖师爷定下的规则是,先构造基类再构造派生类,初始化列表是先于构造函数执行的。
  Person(name)在初始化列表中的顺序可以随意改动的,因为初始化列表的执行顺序只跟声明的顺序有关,跟初始化列表中的先后顺序无关。

1.2 拷贝复制

分别是拷贝构造函数和operator=复制函数:

  1. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
  2. 派生类的operator=必须要调用基类的operator=完成基类的复制。

上面两条的原因和构造函数的一样,就不在赘述。
下面是验证的代码:

#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;}
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;}
protected:int _num; //学号
};
int main()
{Student s1("jack", 18);Student s2(s1);return 0;
}

1.3 构造函数和析构函数的执行顺序

  1. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
  2. 派生类对象初始化先调用基类构造再调派生类构造。
  3. 派生类对象析构清理先调用派生类析构再调基类的析构。
  • 首先,为什么一定先调用基类构造函数再调用派生类的的构造函数呢?
      如果你先调用派生类的构造函数,派生类是继承基类的,那么派生类中就可以使用基类中的属性和行为,但是此时还没有调用基类的构造函数,所以不能这样。

  • 为什么一定先调用派生类的析构函数再调用基类的析构函数呢?
      如果先调用基类的析构函数的话,会释放掉一些变量或指针,那么派生类使用继承过来的这些变量或者指针的时候,它们已经变成了野指针,因此不能如此。

在这里插入图片描述

下面是完整代码,大家可以尝试验证:

#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;return 0;
}

2. 继承和友元

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员

#include <iostream>
using namespace std;class Student;
class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name = "zhangsan"; // 姓名
};class Student : public Person
{
public:protected:int _num; //学号
};void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._num << endl;
}
int main()
{Student s;Person p;Display(p, s);return 0;
}

在这里插入图片描述

从上面图中可以看出。

3. 继承与静态成员

  基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。

#include <iostream>
#include <string>
using namespace std;class Person
{
public:Person(){++_count;++age;}public:static int _count;int  age = 0; // 姓名
};
int Person::_count = 0;class Student : public Person
{
public:protected:int _num; //学号
};int main()
{Student s;Person p;cout << "Person::_count:  "<<Person::_count<<endl;cout << "Person::age:  "<<p.age<<endl;return 0;
}

运行结果是:
在这里插入图片描述

  由此可见,静态成员_count是共有的,只有一个。


  😄 创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看😄

相关文章:

C++之继承<2>【详解】

C之继承&#xff1c;2&#xff1e;【详解】 1. 派生类的默认成员函数1.1 1. 构造成员函数1.2 拷贝复制1.3 构造函数和析构函数的执行顺序 2. 继承和友元3. 继承与静态成员 1. 派生类的默认成员函数 1.1 1. 构造成员函数 派生类的构造函数必须调用基类的构造函数初始化基类的那…...

解决Kafka新消费者组导致重复消费的问题

问题描述&#xff1a;在使用Kafka时&#xff0c;当我们向新的消费者组中添加消费者时&#xff0c;可能会遇到重复消费的问题。本文将介绍一些解决这个问题的方法&#xff0c;帮助开发者更好地处理Kafka中的消费者组和消费偏移量。 Kafka是一个强大的分布式消息队列系统&#xf…...

公允价值会计(fair-value accounting)

《公允价值会计》是2008年经济科学出版社出版图书。 公允价值会计又称市值会计&#xff0c;是指以市场价值或未来现金流量的现值作为资产和负债的主要计量属性的会计模式。随着现代交通和通讯技术的发展&#xff0c;在工业社会中相互分割的市场正在走向世界一体化&#xff0c;…...

【java调取第三方接口,获取数据并保存至数据库】

java调取第三方接口&#xff0c;获取数据并保存至数据库 Overridepublic void doPost() {// 创建Httpclient对象CloseableHttpClient httpClient HttpClients.createDefault();CloseableHttpResponse response null;String resultString "";String url "htt…...

图论01-【无权无向】-图的基本表示-邻接矩阵/邻接表

文章目录 1. 代码仓库2. 图的基本表示的比较3. 邻接矩阵&#xff1a;Array和TreeSet3.1 图示3.2 Array主要代码解析3.3 测试输出3.4 使用TreeSet的代码 4. 邻接表&#xff1a;LinkedList4.1 图示4.2 LinkedList主要代码解析4.3 测试输出 5. 完整代码5.1 邻接表 - Array5.2 邻接…...

Bootstrap的列表组相关知识

目录 01-列表组的相关基础知识02-一个简单的列表组示例03-激活或禁用列表组的一行或多行04-设置列表项的颜色05-给列表项添加徽章 01-列表组的相关基础知识 Bootstrap的list-group是一个用于创建列表组件的CSS类&#xff0c;通常用于显示一个项目列表&#xff0c;如导航菜单或…...

Linux简单安装ffmpeg 实现用PHP压缩音频

一、下载安装 1、官方下载地址&#xff1a;Download FFmpeg 2、下载完上传到服务器然 然后解压就算安装完成了 tar -xf ffmpeg-git-amd64-static.tar.xz 3、然后配置一下全局变量&#xff08;当然也可以不用配置 使用的时候带上文件路径就行&#xff09; cd /usr/bin ln -s…...

Vue解决 npm -v 报错(一)

报错内容&#xff1a; npm WARN config global --global, --local are deprecated. Use --locationglobal instead. 解决方案&#xff1a; 代码&#xff1a; prefix -g 替换为&#xff1a; prefix --locationglobal 原创作者&#xff1a;吴小糖 创作时间&#xff1a;2023.1…...

IP地址是如何定位的

IP地址定位原理和方法 在互联网时代&#xff0c;了解设备或用户的地理位置对于各种应用和服务至关重要&#xff0c;从广告定向到网络安全。IP地址定位是一种常用的方法&#xff0c;允许确定IP地址背后的实际地理位置。本文将介绍IP地址定位的原理和方法。 IP地址基础&#xf…...

【分布式】入门级NCCL多机并行实践 - 02

# 背景知识 大模型和分布式训练对数据的吞吐量以及并行度都有很高的要求&#xff0c;NCCL就是在这个背景下诞生的。 如果你是一个只会写写Python&#xff0c;调用PyTorch和Horovod的算法萌新&#xff0c;可能对于分布式底层的东西不太了解&#xff0c;在下岗热潮中被主管逼着…...

Rust的模式匹配

文章目录 match匹配if let匹配 match匹配 match可以结合枚举使用&#xff0c;例如 enum IpVersion {V4,V6, }fn ParseIpVersion(version: IpVersion) -> String {match version {IpVersion::V4 > String::from("ipv4"),IpVersion::V6 > String::from(&quo…...

操作系统【OS】虚拟机

定义 使用虚拟化技术&#xff0c;将一台物理机器虚化为多台虚拟机器VM&#xff0c;每个虚拟机器都可用独立运行一个操作系统 分类 传统计算机 第一类VMM 第二类VMM...

不写代码、构建一个开源的 ChatGPT,总共需要几步?|Hugging News #1020

每一周&#xff0c;我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新&#xff0c;包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等&#xff0c;我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息&#xff0…...

VBA操作数据库

相关背景&#xff1a; 对于数据分析同学&#xff0c;一般SQL&#xff0c;EXCEL是必备技能&#xff0c;但对于VBA和Python可能有的同学不会&#xff1b;在处理本地数据上(诸如excel、txt|csv文本&#xff09;&#xff0c;后续尝试使用VBA或者Python写一个sql查询的GUI界面&…...

【华为OD机试】HJ26 字符串排序

描述 编写一个程序&#xff0c;将输入字符串中的字符按如下规则排序。 规则 1 &#xff1a;英文字母从 A 到 Z 排列&#xff0c;不区分大小写。 如&#xff0c;输入&#xff1a; Type 输出&#xff1a; epTy 规则 2 &#xff1a;同一个英文字母的大小写同时存在时&#xff0c;…...

哈里斯鹰算法优化BP神经网络(HHO-BP)回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

摆动序列【贪心4】

题目 分析 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {if(nums.size() < 2) return nums.size();int ret 0,left 0,right 0;for(int i 0;i < nums.size()-1;i){right nums[i1] - nums[i];if(right 0) continue;if(left …...

Youtrack Linux 安装

我们考虑最后应该使用的是 ZIP 方式的安装。 按照官方的说法如何设置运行 YouTrack 应该是非常简单的。 准备环境 根据官方的说法&#xff0c;我们需要做的就是下载 Zip 包&#xff0c;然后把 Zip 包解压到指定的目录中就可以了。 下载 当前官方的下载地址为&#xff1a;Ge…...

分类预测 | MATLAB实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络数据分类预测

分类预测 | MATLAB实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络数据分类预测 目录 分类预测 | MATLAB实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现SSA-CNN-LSTM数据分类预测&…...

飞书-多维文档-计算时间差

1. 选择字段类型 如图所示&#xff0c;字段类型选择 公式 2. 编辑公式 单击 公式编辑器 在弹出的公式编辑框中输入公式 TEXT([终结时间]-[开始时间],"HH:MM") [终结时间] 和 [开始时间] 请替换成你的表格中对应的字段名称HH:MM 表示输出的时间格式为 时:分其中 “…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理&#xff1a;检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目&#xff1a;RankRAG&#xff1a;Unifying Context Ranking…...