C++系列-继承

🌈个人主页:羽晨同学 

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

 继承的概念和定义

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

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.xdnf.cn/news/1550543.html

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

相关文章

【PyTorch】生成对抗网络

生成对抗网络是什么 Generative Adversarial Nets&#xff0c;简称GAN GAN&#xff1a;生成对抗网络 —— 一种可以生成特定分布数据的模型 《Recent Progress on Generative Adversarial Networks (GANs): A Survey》 《How Generative Adversarial Networks and Its Varian…

基于Megatron-LM从0到1完成GPT2模型预训练、模型评估及推理

随着 ChatGPT 迅速爆火&#xff0c;引领基于Transformer架构的大模型从幕后走到台前。但 ChatGPT 的成功并不是一蹴而就&#xff0c;而是&#xff0c;经过了从早期的 GPT1 到 GPT2&#xff0c;之后到 GPT3 和 InstructGPT、然后到GPT3.5和ChatGPT&#xff0c;直到如今的多模态大…

一钉多用:自攻螺钉在家居与工业领域的广泛应用

自攻螺钉的结构要素有哪些重要特点&#xff1f; 自攻螺钉适用于非金属或软金属&#xff0c;不需要配合预先开好的孔和攻牙。自攻螺钉的尖头设计使其能够“自我攻入”材料中&#xff1b;而普通螺丝通常是平头&#xff0c;规格一致。自攻螺钉的关键在于&#xff0c;打孔时不需要进…

【JavaEE初阶】网络原理

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 ⽹络互连 IP地址 端口号 协议 协议分层 优势 TCP/IP 五层网络模型 数据在网络通信中的整体流程 封装和分用 封装 分用 ⽹络互连 随着时代的发展&#xff0c;越来越需…

Angular基础学习(入门 --> 入坑)

目录 一、Angular 环境搭建 二、创建Angular新项目 三、数据绑定 四、ngFor循环、ngIf、ngSwitch、[ngClass]、[ngStyle]、管道、事件、双向数据绑定--MVVM 五、DOM 操作 &#xff08;ViewChild&#xff09; 六、组件通讯 七、生命周期 八、Rxjs 异步数据流 九、Http …

51单片机的光照强度检测【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块光照传感器按键蜂鸣器LED等模块构成。适用于光照强度检测、光照强度测量报警等相似项目。 可实现功能: 1、LCD1602实时显示光照强度信息 2、光照强度传感器&#xff08;电位器模拟&#xff09;采集光照信息 3、可…

X86架构(九)——保护模式的进入

全局描述符表 全局描述符表(Global Descriptor Table,GDT)是保护模式下非常重要的一个数据结构。 在保护模式下&#xff0c;对内存的访问仍然使用段地址和偏移地址&#xff0c;在每个段能够访问之前&#xff0c;必须先行设置好 GDT 的地址&#xff0c;并加载全局描述符表寄存…

emp.dll丢失怎么解决,快来试试这个几个解决方法

在日常使用电脑玩游戏的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中最常见的就是“emp.dll丢失”。那么&#xff0c;emp.dll到底是什么&#xff1f;它为什么会丢失&#xff1f;丢失后会对我们的电脑产生什么影响&#xff1f;本文将为您详细解析emp.dll的概念…

[BUUCTF从零单排] Web方向 03.Web入门篇之sql注入-1(手工注入详解)

这是作者新开的一个专栏《BUUCTF从零单排》&#xff0c;旨在从零学习CTF知识&#xff0c;方便更多初学者了解各种类型的安全题目&#xff0c;后续分享一定程度会对不同类型的题目进行总结&#xff0c;并结合CTF书籍和真实案例实践&#xff0c;希望对您有所帮助。当然&#xff0…

打造高业绩朋友圈:策略与实践

在数字化时代&#xff0c;朋友圈不仅是个人生活的展示窗口&#xff0c;更是商业变现的有力平台。许多人通过精心经营朋友圈&#xff0c;实现了财富的增长&#xff0c;甚至达到了年入百万的惊人业绩。朋友圈已成为普通人实现逆袭的重要战场。 要打造一个业绩过万的朋友圈&#…

关于武汉芯景科技有限公司的IIC电平转换芯片XJ9509开发指南(兼容PCa9509)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.VCCA1.35V,VCCB5V,A1输入&#xff0c;B1输出 2.VCCA1.35V,VCCB5V,B1输入&#xff0c;A1输出 3.VCCA1.35V,VCCB5V,A2输入&#xff0c;B2输出 4.VCCA1.35V,VCCB5V,B2输入&#xff0c;A2输出

升级 Windows 后如何恢复丢失的文件

升级到 Windows 11 后可以恢复丢失的文件&#xff01;阅读帖子直到最后&#xff0c;了解如何做到这一点。 为了获得安全更新并使用最新的操作系统&#xff0c;人们会升级到最新版本的 Windows。然而&#xff0c;在这样做的过程中&#xff0c;许多人丢失了他们的重要文件&#…

基于SpringBoot+Vue+MySQL的体育商城系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网的飞速发展&#xff0c;电子商务已成为人们日常生活中不可或缺的一部分。体育用品市场作为其中的一个重要分支&#xff0c;也逐渐向线上转移。基于SpringBootVueMySQL的体育商城系统应运而生&#xff0c;旨在通过构建…

优秀的拆分C++

题目&#xff1a; 样例解释&#xff1a; 样例1解释 6422221 是一个优秀的拆分。注意&#xff0c;6222 不是一个优秀的拆分&#xff0c;因为拆分成的 3 个数不满足每个数互不相同。 思路&#xff1a; 题目大致意思是说给定一个正整数NN&#xff0c;让你用二进制表示&#xff08;…

PDCA优化任务流程

这里写目录标题 一、背景二、PDCA重要性与必要性概念PDCA循环的重要性 三、PDCA分析这次任务的执行任务描述分析原因&#xff1a;结合PDCA分析&#xff1a;提高办法&#xff1a; 四、总结 一、背景 汇报任务完成情况&#xff0c;未提交实际成果。 本次总结旨在通过PDCA循环的视…

鸿蒙开发(NEXT/API 12)【硬件(振动开发1)】振动

通过最大化开放马达器件能力&#xff0c;振动器模块服务拓展了原生马达服务&#xff0c;实现了振动与交互融合设计&#xff0c;从而打造出细腻精致的一体化振动体验和差异化体验&#xff0c;提升用户交互效率、易用性以及用户体验&#xff0c;并增强品牌竞争力。 运作机制 Vi…

学习docker第二弹------基本命令[帮助启动类命令、镜像命令、容器命令]

docker目录 前言基本命令帮助启动类命令停止docker服务查看docker状态启动docker重启docker开机启动docker查看概要信息查看总体帮助文档查看命令帮助文档 镜像命令查看所有的镜像 -a查看镜像ID -q在仓库里面查找redis拉取镜像查看容器/镜像/数据卷所占内存删除一个镜像删除多个…

机器学习:opencv--背景建模

目录 一、背景建模是什么&#xff1f; 二、背景建模的目的 三、背景建模的方法及原理 四、代码实现 1.创建卷积核 2.创建混合高斯模型 3.处理图像 4.绘制人形轮廓 5.条件退出 一、背景建模是什么&#xff1f; 指在计算机视觉中&#xff0c;从视频序列中提取出静态背景…

Anaconda虚拟环境默认路径在C盘怎么更改

笔者已经新建好了虚拟环境并且安装了对应库&#xff0c;输入conda env list查询发现虚拟环境竟然安装到了C盘(&#xff61;•́︿•̀&#xff61;)&#xff0c;为避免下一次创建虚拟环境出错&#xff0c;笔者现在修改默认路径置D盘&#xff08;软件安装盘&#xff09; 参考两…

ROS学习笔记(四):使用 `ros2 run usb_cam usb_cam_node_exe` 启动 USB 摄像头

文章目录 前言1 安装 usb_cam 包2 启动 USB 摄像头3 订阅相机发布的节点信息并进行可视化3.1 使用 rqt_image_view3.2 使用 image_view3.3 使用 rviz 4 常见问题与解决方案4.1 摄像头未被识别4.2 相机显示异常4.3 如何指定不同的相机4.4 摄像头参数调整 5. 调试信息 5. 结论 前…