C++系列-继承

news2024/9/30 11:35:24

🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

 继承的概念和定义

继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行拓展,增加功能,这样可以产生新的类,叫做派生类,继承呈现了面向对象的程序设计的层次结构,继承是类设计层次的复用

class Person
{
public:
	Person()
	{}
	void Print()
	{
		cout << "name:" << _name << endl;
		cout << "age:" << _age << endl;
		cout<<_tel<<endl;
	}
	string _name = "peter";//姓名
protected:
	int _age = 18;
	//父类定义本质,不想被子类继承
private:
	int _tel = 110;
};
//继承的父类的成员
class Student :public Person
{
public:
	void Func()
	{
		//子类用不了(不可见)
		//cout << _tel << endl;
		cout << _name << endl;
		cout << _age << endl;
	}
protected:
	int _stuid;//学号
};
class Teacher :public Person
{
protected:
	int _jobid;//工号
};

在这个代码当中,我们简单的使用继承创建了两个对象。

 所以,我们看到的是Person是父类,也被叫做基类,Student是子类,也称作派生类。


继承管理和访问限定符 

继承基类成员访问方式的变化。

 

在这其中,如果我们使用public继承和类成员是public成员或者protected成员,是可以直接使用成员,其他的就不可以,例如:

class Student :public Person
{
public:
	void Func()
	{
		//子类用不了(不可见)
		cout << _tel << endl;
		cout << _name << endl;
		cout << _age << endl;
	}
protected:
	int _stuid;//学号
};

在这里,我们的_tel在Person中时private修饰的,所以派生类中不能进行调用。

但是,父类的私有成员变量是可以父类的成员函数来间接调用的,例如:

class Person
{
public:
	Person()
	{}
	void Print()
	{
		cout << "name:" << _name << endl;
		cout << "age:" << _age << endl;
		cout<<_tel<<endl;
	}
	string _name = "peter";//姓名
protected:
	int _age = 18;
	//父类定义本质,不想被子类继承
private:
	int _tel = 110;
};

在实际使用中一般使用的都是public继承,几乎很少使用protected/private继承 

派生类和基类对象的赋值转换

我们假如让p=s,这个是可以实现的,但这个实现的逻辑并不是类型转换,而是一种特殊的语法规则,不会产生任何的中间变量,我们可以看下面的代码实现逻辑。

int main()
{
	Student s;
	Person p;
	//跟下面机制不一样
	//特殊语法规则:不是类型转换,中间没有产生临时变量
	p = s;
	Person* ptr = &s;
	Person& ref = s;
	ptr->_name += 'x';
	ref._name += 'y';
	s._name += 'z';
	return 0;
}

  • 基类对象不能赋值给派生类对象。
  • 派生类对象可以赋值给基类的对象/基类的指针/基类的引用,这里我们可以叫做切片或者切割。

那类型转换下的情况是什么吗?

这个就是我们经常说到的,截断和提升。 

继承中的作用域

基类和派生类都有独立的作用域

子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫做隐藏,也叫做重定义(在子类成员函数中,可以使用基类:基类成员显示访问)

如果是成员函数之间的隐藏,只要函数名相同就能构成隐藏。

在实际中,最好不要在继承体系里面定义同名的成员

#include<iostream>
using namespace std;
//student的_num和Prson的_num构成隐藏关系,可以看出代码虽然可以运行,但是非常容易混淆
class Person
{
protected:
	string _name = "小李子";
	int _num = 111;
};
class Student :public Person
{
public:
	void Print()
	{
		cout << "姓名" << _name << endl;
		cout << "学号" << _num << endl;//隐藏,重定义
		cout << "学号" << Person::_num << endl;
	}
protected:
	int _num = 999;
};
int main()
{
	Person p;
	Student s;
	s.Print();
	return 0;
}

你看,这里面就涉及到了隐藏和重定义。

 派生类的默认成员函数

6个默认成员函数

  • 初始化和清理
  1. 构造函数主要完成初始化工作
  2. 析构函数主要完成清理工作
  • 拷贝复制
  1. 拷贝构造是使用同类对象初始化创建对象
  2. 赋值重载主要是把一个对象赋值给另一个对象
  • 取地址重载
  1. 主要是普通函数和const对象取地址,这两个很少会自己实现

 在子类中,父类的那部分调用父类的什么函数,这个就叫做复用。

构造:

构造的时候,我们要先父后子,因为子类中关于父类成员的部分会用到父类的构造,

析构:

析构的时候,我们要先子后父,因为子类的析构可能会用到父类的析构函数。

class Person
{
public:
	Person(const char* name = "")
		:_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;
		delete[] _str;
	}
protected:
	string _name;
	char* _str = new char[10] {'x', 'y', 'z'};
};
class Student :public Person
{
public:
	//父类构造显示调用,可以保证先父后子
	Student(const char*name="",int x=0,const char*address="")
		:_x(x)
		,_address(address)
		,_name(Person::_name+'x')
		,Person(name)
	{}
	Student(const Student&st)
		:Person(st)
		,_x(st._x)
		,_address(st._address)
	{}
	Student& operator=(const Student& st)
	{
		if (this != &st)
		{
			Person::operator=(st);
			_x = st._x;
			_address = st._address;
		}

		return *this;
	}
	//由于多态,析构函数的名字会被统一处理成destructor()
	//父类析构不能显示调用,因为显示调用不能保证先子后父
	~Student()
	{
		//析构函数会构成隐藏,所以这里要指定类域
		cout << "Student()" << endl;
		cout << _str << endl;
	}
protected:
	int _x = 1;
	string _address = "sdasa";
	string _name;
};

好了,本次的文章就到这里了,我们下次再见。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSL VPN | Easyconnect下载安装使用 (详尽)

EasyConnect是一款远程连接工具&#xff0c;为用户提供简便、快捷的远程访问和控制解决方案。 目录 下载 安装 使用 卸载 下载 通过链接进入官网技术支持板块 深信服技术支持-简单、高效、自助化服务 (sangfor.com.cn)https://support.sangfor.com.cn/ 选择软件下载 在安…

获取本函数所在代码域内的所有局部变量和值以字典形式返回locals()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 获取本函数所在代码域内的 所有局部变量和值 以字典形式返回 locals() 选择题 关于以下代码输出的结果说法正确的是&#xff1f; a 10 def x(): b 20 print(locals()) print("【执行…

二值图像的面积求取的两种方法及MATLAB实现

一、引言 面积在数字图像处理中经常用到&#xff0c;在MATLAB中&#xff0c;计算二值图像的面积通常可以通过两种主要方法实现&#xff1a;遍历法和直接利用bwarea函数。下面将分别介绍这两种方法的原理和相应的MATLAB代码示例。 二、遍历法计算二值图像面积的原理和MATLAB代码…

护眼落地台灯品牌前十名:十大全网超高热度品牌汇总

十大护眼路灯台灯有哪些&#xff1f;在众多照明灯具产品中&#xff0c;护眼落地台灯能够提供适合多场景、大氛围的舒适照明&#xff0c;对于学生、工作群体来说能够有效的提高光线质量&#xff0c;减少不良光线带来的近视风险。可是市场品牌繁多&#xff0c;很容易选购到劣质的…

golang web笔记-2.请求request

什么是request http消息分为request&#xff08;请求&#xff09; 和 response&#xff08;响应&#xff09; request&#xff1a;在go中是一个struct&#xff0c;代表了客户段发送的http请求&#xff0c;已可以通过request 的方法访问请求中的cookie、URL、User Agent&#xf…

【论文阅读笔记】TOOD: Task-aligned One-stage Object Detection

论文代码&#xff1a;https://github.com/fcjian/TOOD 文章目录 论文小结论文简介论文方法Task-aligned Head&#xff08;T-Head&#xff09;T-Head伪代码解释 Task Alignment Learning&#xff08;TAL&#xff09;Task-aligned Sample AssignmentTask-aligned Loss 论文实验消…

STM32F1+HAL库+FreeTOTS学习15——互斥信号量

STM32F1HAL库FreeTOTS学习15——互斥信号量 1. 优先级翻转2. 互斥信号量3. 相关API函数&#xff1b;3.1 互斥信号量创建3.2 获取信号量3.3 释放信号量3.4 删除信号量 4. 操作实验1. 实验内容2. 代码实现3. 运行结果 上期我们介绍了数值信号量。这一期我们来介绍互斥信号量 1. 优…

Hadoop FileSystem Shell 常用操作命令

提示&#xff1a;本文章只总结一下常用的哈&#xff0c;详细的命令大家可以移步官方的文档&#xff08;链接贴在下面了哈&#x1f923;&#xff09;— HDFS官方命令手册链接。 目录 1. cat 命令&#xff1a;查看 HDFS 文件内容2. put 命令&#xff1a;将本地文件上传到 HDFS3.…

基于VirtualBox和Ubuntu的虚拟环境搭建

VirtualBox简介 VirtualBox 是一款开源虚拟机软件。 是由德国 Innotek 公司开发&#xff0c;由Sun Microsystems公司出品的软件&#xff0c;使用Qt编写&#xff0c;在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。简单易用&#xff0c;可虚拟的系统包括Windows&…

浅谈汽车智能座舱如何实现多通道音频

一、引言 随着汽车智能座舱的功能迭代发展&#xff0c;传统的 4 通道、6 通道、8 通道等音响系统难以在满足驾驶场景的需求&#xff0c;未来对于智能座舱音频质量和通道数会越来越高。接下来本文将浅析目前智能座舱如何实现音频功放&#xff0c;以及如何实现多路音频功放方案。…

Library介绍(三)

环境描述 工作条件 一般lib文件里面包含了芯片的工作条件即operation conditions&#xff0c;其指定了工艺&#xff08;process&#xff09;、温度&#xff08;temperature&#xff09;和电压&#xff08;voltage&#xff09;&#xff0c;见图1。 其中&#xff0c;process代表了…

10款超好用的图纸加密软件推荐!2024企业图纸加密最佳选择!

在现代企业中&#xff0c;保护知识产权和敏感数据显得尤为重要。尤其是工程设计、建筑图纸等专业文件&#xff0c;若遭到泄露&#xff0c;可能导致巨大的经济损失和竞争优势的丧失。为了帮助企业有效保护图纸&#xff0c;本文将推荐10款超好用的图纸加密软件。 1.安秉图纸加密软…

【CSS in Depth 2 精译_043】6.5 CSS 中的粘性定位技术 + 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09;第二章 相对单位&#xff08;已完结&#xff09;第三章 文档流与盒模型&#xff08;已完结&#xff09;第四章 Flexbox 布局&#xff08;已…

在起草行业标准时,如何确保格式统一?

一、遵循相关规范 1. 严格按照国家有关标准编写规范以及行业特定的标准编写指南进行起草。熟悉并掌握规范中对于标准结构、条款编号、字体字号、图表格式等方面的具体要求。 2. 参考已发布的同行业成熟标准的格式&#xff0c;学习其成功的格式布局和表达形式。 二、建立模板 1…

9.24-k8s服务发布

Ingress 使用域名发布 K8S 服务 部署项目 一、先部署mariadb [rootk8s-master ~]# mkdir aaa [rootk8s-master ~]# cd aaa/ [rootk8s-master aaa]# # 先部署mariadb [rootk8s-master aaa]# # configmap [rootk8s-master aaa]# vim mariadb-configmap.yaml apiVersion: v1 ki…

Leecode刷题之路第五天之最长回文子串

题目出处 05-最长回文子串 题目描述 个人解法 思路&#xff1a; 1.找出所有子串 2.过滤回文子串 3.回文子串长度排序 4.输出最长回文子串 代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo 官方解法 最长回文子串 方法1&#xff1a;动态规划 思路&…

新能源汽车储充机器人:能源高效与智能调度

新能源汽车储充机器人&#xff1a;开启能源高效利用与智能调度的未来之门 随着全球能源危机的日益加剧和环境污染问题的不断恶化&#xff0c;新能源汽车成为了未来交通领域的重要发展方向。然而&#xff0c;新能源汽车的普及不仅需要解决电池技术的瓶颈&#xff0c;还需要构建一…

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】 一、TFLM是什么&#xff1f;二、TFLM开源项目2.1 下载TFLM源代码2.2 TFLM基准测试说明2.3 TFLM基准测试命令 三、TFLM初步体验3.1 PC上运行Keyword基准测试3.2 PC上运行Person detection基准测试3.3 No module nam…

netty之基础aio,bio,nio

前言 在Java中&#xff0c;提供了一些关于使用IO的API&#xff0c;可以供开发者来读写外部数据和文件&#xff0c;我们称这些API为Java IO。IO是Java中比较重要知识点&#xff0c;且比较难学习的知识点。并且随着Java的发展为提供更好的数据传输性能&#xff0c;目前有三种IO共…

怎么在Windows系统中使用Chrome的语音搜索功能

在Windows系统中使用谷歌浏览器的语音搜索功能是一种快速且方便的搜索方式。本文将详细介绍如何在Windows系统中启用和使用Chrome的语音搜索功能。 &#xff08;本文由https://chrome.cmrrs.com/站点的作者进行编写&#xff0c;转载时请进行标注。&#xff09; 一、 启用语音搜…