C++:面向对象三大特性之一:继承

news2024/11/15 21:49:48

继承

  • 1.继承理解
  • 2.继承方式引起访问变化
    • 表格
    • 表格理解
  • 3.赋值转换
    • 1.普通对象赋值
    • 2.继承对象赋值:赋值转换
      • 注意
  • 4.继承的作用域
  • 5.派生类默认成员函数
    • 1.构造函数
    • 2.析构函数
    • 3.拷贝构造
    • 4.赋值重载
  • 6.继承与友元
  • 7.继承与静态成员

1.继承理解

继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。

继承关系可以理解为is a的关系,即子类是一个特殊的父类。

比如学生是一种人,老师是一种人,狗是动物等。

在这里插入图片描述

2.继承方式引起访问变化

表格

在这里插入图片描述

表格理解

1.对于父类中的私有成员,无论何种继承,在子类中都不可见。(即虽然被继承到了子类,但是不能在子类内和子类外直接使用)
2.默认的权限大小:public > protected > private
3.对于继承后权限的变化,即:继承方式的权限与父类成员的原权限的最小值
4.和private相比,父类protected成员是只能在子类中使用,而子类对象无法在子类外使用,因此可以看出访问限定符因为继承关系而出现。
5.class类默认的继承方式是private,struct类默认的继承方式是public,但是建议把继承方式显示写出来。

3.赋值转换

1.普通对象赋值

在我们之前的学习中,会有不同类型的值赋值时,如果可以赋值,会产生临时变量,是将临时变量进行赋值。

在这里插入图片描述
在这里插入图片描述

临时变量具有常性,因此如果需要用引用接收时,需要加const。

2.继承对象赋值:赋值转换

在继承中,子类继承了父类之后再对其进行扩展。那么子类就会有父类有的那一部分。

子类对象对父类对象赋值时,不会产生临时变量,而是直接将继承父类的那一部分赋值过去。

注意

1.子类对象可以赋值给父类的对象,指针,引用。

	赋值给对象:将子类中继承父类的那一部分赋值给父类对象。

	赋值给指针:指针指向子类中继承父类的那一部分。

	赋值给引用:该父类引用是子类中继承父类的那一部分的别名

2.父类对象不能赋值给子类对象

3.基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI(RunTime Type Information)的dynamic_cast 来进行识别后进行安全转换。(先了解即可)

在这里插入图片描述
示例:

class Person
{
public:
	void Print()
	{
		cout << "name:" << _name << " age:" << _age << endl;
	}
	string _name = "张三"; // 姓名
	int _age = 18; // 年龄
};

class Student : public Person
{
public:
	void Print()
	{
		cout << "name:" << _name << "   age:" << _age << endl;
	}
protected:
	int _stunum = 110;// 学号
};

int main()
{
	Student st;
	st.Print();
	Person p = st;
	p._name += "xxxx";
	p._age++;
	p.Print();

	Person* ptr = &st;
	ptr->_name += "x";
	ptr->_age++;

	Person& ref = st;
	ref._name += "y";
	ref._age++;

	st.Print();
	return 0;
}

输出结果:
在这里插入图片描述

4.继承的作用域

1.父类和子类都有各自的类域

2.隐藏(重定义)

​ 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问。

​ 子类和父类中有同名函数就构成隐藏,不需要函数的返回值参数这些相同。

注意:同名函数的隐藏不是函数重载!!!函数重载是在同一个域中,而父类和子类具有各自的类域。

3.对于隐藏的成员或者成员函数,可以通过基类::基类成员 显示访问

4.如果子类中没有该成员或成员函数,则直接访问,不需要再进行指定(注意访问权限的限制)

示例:

class Person
{
public:
    void func()
	{
		cout << "I am a person" << endl;
	}
	void Print()
	{
		cout << "name:" << _name << " age:" << _age << endl;
	}
	string _name = "张三"; // 姓名
	int _age = 18; // 年龄
};
class Student : public Person
{
public:
	void Print()
	{
		cout << "name:" << _name << "   age:" << _age << endl;
		Person::Print(); //指定类域
		func(); //由于子类中没有,因此不需要指定类域
	}
protected:
	string _name = "李四";
	int _stunum = 110;// 学号
};
int main()
{
	Student st;
	st.Print();
	st.Person::Print();
}

输出结果:
在这里插入图片描述

5.派生类默认成员函数

首先我们要明白:继承的父类成员等为一个整体,我们可以将其理解成为一个类成员!!!

下面对于子类的默认成员函数的行为进行梳理:

1.构造函数

子类的构造函数会去调用父类的构造函数来初始化自己继承的父类的那一部分,如果父类有默认构造函数则会去调用其的默认构造函数,如果父类没有就需要在子类的初始化列表部分显式调用父类的构造函数。

构造函数调用顺序:先父后子

显式调用格式:父类类名(参数)

2.析构函数

子类的析构函数在结束时会自动调用父类的析构函数。这样是为了保证析构的顺序是先子后父。

析构函数调用顺序:先子后父

注意:子类的析构函数会隐藏父类的析构函数。

虽然父类的析构函数和子类的析构函数看起来函数名不同,但是它们仍然构成隐藏,因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同,因此编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。

3.拷贝构造

子类的拷贝构造需要调用父类的拷贝构造进行完成(在初始化列表处)。

4.赋值重载

子类的赋值重载对于父类那部分必须显式调用父类的赋值重载,因为它们构成了隐藏,如果不显示调用,那么子类的赋值重载就会一直调用子类的赋值重载,那么就会栈溢出。

6.继承与友元

这里只需要知道一个点:

友元关系不能继承,就像你爸的朋友不是你的朋友一样。

7.继承与静态成员

这里只需要知道一个点:

父类的静态成员属于父类和其所有的子类。即整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。

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

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

相关文章

驶向成功:如何选择适合国际拓展的完美CRM

一、出海企业应该怎么选择CRM&#xff1f; 出海企业在选择CRM系统时&#xff0c;需要考虑行业特性以及在对外业务过程中可能遇到的问题。接触了一些出海企业客户&#xff0c;总结了以下出海企业在选择CRM时的诉求。 1、合法合规风险 出海企业的业务遍布不同国家地区&#xff…

【考研数学】基础跟武忠祥,同步刷《660》的正确方法

听我的&#xff0c;现在立刻马上停下来 你这不是在做题&#xff0c;你这是在看题&#xff0c;效果最差的那种&#xff0c;做完过两天就忘的一干二净了 我不敢说我特别会学习考研数学&#xff0c;但是我考研的时候&#xff0c;最后数学一的成绩是120&#xff0c;不算特别好&am…

搞定这些python自动化测试面试题与答案汇总,offer拿到手软!

1、什么项目适合做自动化测试&#xff1f; 关键字&#xff1a;不变的、重复的、规范的 1&#xff09;任务测试明确&#xff0c;需求不会频繁变动 2&#xff09;项目周期要足够长 3&#xff09;自动化测试脚本可重复使用&#xff0c;比如&#xff1a;比较频繁的回归测试 4&…

01-大语言模型发展

AI大模型的相关的一些基础知识&#xff0c;一些背景和基础知识。 多模型强应用AI 2.0时代应用开发者的机会。 0 大纲 AI产业的拆解和常见名词应用级开发者&#xff0c;在目前这样一个大背景下的一个职业上面的一些机会实战部分的&#xff0c;做这个agent&#xff0c;即所谓智…

基于pytest自动化测试框架分享

一、pytest运行方式与基本规范 1.简单介绍 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个特点&#xff1a; 简单灵活&#xff0c;容易上手支持参数化能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做Web UI自动化测试&#xff0…

第 7 章 导航实现(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 准备工作 请先安装相关的ROS功能包&#xff1a; 安装 gmapping 包(用于构建地图)&#xff1a; sudo apt inst…

详细UI色彩搭配方案分享

UI 配色是设计一个成功的用户界面的关键之一。UI 配色需要考虑品牌标志、用户感受、应用程序的使用场景&#xff0c;这样可以帮助你创建一个有吸引力、易于使用的应用程序。本文将分享 UI 配色的相关知识&#xff0c;帮助设计师快速构建 UI 配色方案&#xff0c;以满足企业的需…

webgl canvas系列——animation中基本旋转、平移、缩放(模拟冒泡排序过程)

文章目录 ⭐前言⭐canvas绘制图片&#x1f496;状态保存和恢复&#x1f496;移动、旋转、缩放、变形&#x1f496;移动绘制一个渐变的box&#x1f496;旋转&#x1f496;缩放 ⭐模拟冒泡排序过程⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享webgl canvas系…

EMD分解

ref&#xff1a;【EMD经验模态分解-哔哩哔哩】 https://b23.tv/LfepZjU 流程&#xff1a; IMF 固有模态函数 imf1 迭代直到是一个imf 8次迭代后&#xff0c;满足是一个imf residual的得到&#xff1a;原始信号-均值&#xff08;上下包络线的均值&#xff09; imf2 为什么时序…

【公司UI自动化学习】

公司课程链接&#xff1a;https://l.jd.com/student/project/project.du?project_id697509403 公司的课程&#xff0c;是给一个学习方向。 一、 PC自动化 1&#xff09;什么项目适合 2&#xff09;PC自动化介入时间点 3&#xff09;自动化率&#xff1a; 频繁改动的&…

【Harmony3.1/4.0】笔记二

概述 列表是一种复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;内容超过屏幕大小时&#xff0c;可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集&#xff0c;例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求&#xff08;如通讯录、…

深度学习500问——Chapter08:目标检测(2)

文章目录 8.2.4 R-FCN 8.2.5 FPN 8.2.6 Mask R-CNN 8.2.4 R-FCN R-FCN 有哪些创新点 R-FCN仍然属于two-stage目标检测算法&#xff1a;RPN R-FCN Fully convolutional位置敏感得分图&#xff08;position-sentive score maps&#xff09; our region-based detector is ful…

java-Spring-入门学习-第二天(单例模式和多例模式)

目录 Bean作用域 单例模式(默认可以不写) Spring下的 AutoWired 依赖注入 JaveEE下的 Resource 依赖注入 多例模式 Bean作用域 ​在Spring框架中&#xff0c;Bean是按照作用域来创建的&#xff0c;常见的作用域有两种&#xff1a;Singleton 和 Prototype。Singleton (单例…

6.SpringBoot 日志文件

文章目录 1.日志概述2.日志作用3.使用和观察日志3.1如何观察日志3.2使用日志3.3日志级别3.4日志持久化3.5日志分割 4.日志框架4.1门面模式(外观模式)4.2 SLF4J框架介绍4.3 日志格式的说明4.3.1日志名称 5.日志颜色设置6.总结 大家好&#xff0c;我是晓星航。今天为大家带来的是…

【Java】HashMap、HashTable和ConcurrentHashMap的区别

文章目录 区别一、HashMap1.1基本定义与特性1.2工作原理与实现1.3常用方法1.4性能与优化 二、HashTable三、ConcurrentHashMap3.1基本特点3.2实现原理3.3常用方法3.4适用场景3.5性能优化 HashTable、HashMap和ConcurrentHashMap之间的区别主要体现在线程安全、继承关系与实现接…

(2024|ICLR,变分扩散模型(VDM),可学习编码器,时间相关的均值函数)DiffEnc:使用学到的编码器进行变分扩散

DiffEnc: Variational Diffusion with a Learned Encoder 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 变分扩散模型的基础 3. DiffEnc 4. 编码器和生成模型的参数化 …

Linux--地址空间

目录 看一个现象 基本概念 细节问题--理解它 1.如何理解地址空间&#xff1f; 2.为什么要有地址空间&#xff1f; 3. 进一步了解页表和写时拷贝 4.如何理解虚拟地址&#xff1f; 看一个现象 先通过一段代码&#xff0c;看一看现象 int g_val 100;int main() {printf(&quo…

Linux 认识与学习Bash——2

1 read 从键盘读取变量的值 read 后面不带变量&#xff0c;那么默认会给REPLY变量赋值 #!/bin/bash echo -n "请输入你的名字&#xff1a;" read name echo "欢迎您 $name" echo "----------------"echo -n "请输入你的名字2&#xff1a;&q…

我与深拷贝

前言 最近在掘金读到了一篇文章《Radash 能取代 Lodash&#xff1f;&#xff1f;&#xff1f;真幽默 - 掘金》&#xff0c;文章的评论区讨论起了深拷贝。"深拷贝" 我的"老朋友"&#xff0c;还记得在学习我人生中的第二道面试题的时候认识了它&#xff0c;…

CSS 画一个三角形

一、前言 在前端开发的时候&#xff0c;我们有时候会需要用到一个三角形的形状&#xff0c;比如地址选择或者播放器里面播放按钮 通常情况下&#xff0c;我们会使用图片或者svg去完成三角形效果图&#xff0c;但如果单纯使用css如何完成一个三角形呢&#xff1f; 实现过程似…