C++中的继承(1)

1.继承的概念

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

对于下面的两个类来说,学生类和老师类都具有一个共同的身份识别的函数identity(),还有相同的名字,地址,年龄,电话等,唯一不同的地方是学生的学号以及老师的职称。对于这些相同搞得东西设计到一个类中完全是冗余的。

#include<iostream>
using namespace std;
class Student
{
public:
	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
	void identity()
	{
		// ...
	}
	// 学习 
	void study()
	{
		// ...
	}
protected:
	string _name = "peter"; // 姓名 
	string _address; // 地址 
	string _tel; // 电话 
	int _age = 18; // 年龄 
	int _stuid; // 学号 
};
class Teacher
{
public:
	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
		void identity()
	{
		// ...
	}
	// 授课 
	void teaching()
	{
		//...
	}
protected:
	string _name = "张三"; // 姓名 
	int _age = 18; // 年龄 
	string _address; // 地址 
	string _tel; // 电话 
	string _title; // 职称 
};
int main()
{
	return 0;
}

我们使用继承的概念实现一个person的类,从而让student,teacher这两个类进行复用。

#include<iostream>
using namespace std;
class person
{
public:
	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
	void identity()
	{
		// ...
	}
protected:
	string _name = "张三"; // 姓名 
	string _address; // 地址 
	string _tel; // 电话 
	int _age = 18; // 年龄 

};
class Student:public person
{
public:
	// 学习 
	void study()
	{
		// ...
	}
protected:
	int _stuid; // 学号 
};
class Teacher :public person
{
public:
	// 授课 
	void teaching()
	{
		//...
	}
protected:
	string _title; // 职称 
};
int main()
{
	Student s;
	Teacher t;
	s.identity();
	t.identity();
	return 0;
}

2.继承的定义

下面我们看到Person是基类,也称作父类。Student是派生类,也称作子类。(因为翻译的原因,所以 既叫基类/派生类,也叫父类/子类) 

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

 

  •  基类private成员在派生类中⽆论以什么方式继承都是不可见的。这⾥的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派⽣类对象不管在类里面还是类外面都不能去访问它。

  • 基类private成员在派⽣类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派⽣类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。

  • 实际上面的表格我们进行⼀下总结会发现,基类的私有成员在派⽣类都是不可见。基类的其他成员在派⽣类的访问方式==Min(成员在基类的访问限定符,继承方式),并且public>protected>private。(意思就是使用public继承,父类的public成员在子类也是public成员,protected成员同上,在protected继承中,因为最小的访问关系是protected,所以所有成员都是protected成员,private继承同上
  • 使⽤关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
  • 在实际运⽤中⼀般使⽤都是public继承,⼏乎很少使⽤protetced/private继承,也不提倡使⽤protetced/private继承,因为protetced/private继承下来的成员都只能在派⽣类的类⾥⾯使⽤,实际中扩展维护性不强。

3.继承类模板

 

#define CONTAINER std::vector
namespace liiing
{
	//template<class T>
	//class vector
	//{};
	// stack和vector的关系,既符合is-a,也符合has-a
	template<class T>
	class stack : public CONTAINER<T>
	{
	public:
		void push(const T& x)
		{
			// 基类是类模板时,需要指定⼀下类域
			// 否则编译报错:error C3861: “push_back”: 找不到标识
			// 因为stack<int>实例化时,也实例化vector<int>了           
			// 但是模版是按需实例化,push_back等成员函数未实例化,所以找不到
            //使用#define就可以实现方便,重定义的好处就能体现
			CONTAINER<T>::push_back(x);
		}

		void pop()
		{
			CONTAINER<T>::pop_back();
		}

		const T& top()
		{
			return CONTAINER<T>::back();
		}

		bool empty()
		{
			return CONTAINER<T>::empty();
		}
	};

4.派生类和基类之间的转化

  • public继承的派生类对象可以赋值给基类的指针/基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中基类那部分切出来,基类指针或引用指向的是派生类中切出来的基类那部分。
  • 基类对象不能赋值给派生类对象。
  • 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针 是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使⽤RTTI(Run-Time TypeInformation)的dynamic_cast来进行识别后进行安全转换。(ps:这个我们后面类型转换章节再单独专门讲解,这里先提⼀下)

 

class Person
{
protected:
	string _name; // 姓名 
	string _sex; // 性别 
	int _age; // 年龄 
};
class Student : public Person
{
public:
	int _No; // 学号 
};
int main()
{
	Student sobj;
	// 1.派⽣类对象可以赋值给基类的指针/引⽤ 
	Person* pp = &sobj;
	Person& rp = sobj;

	// ⽣类对象可以赋值给基类的对象是通过调⽤后⾯会讲解的基类的拷⻉构造完成的 
	Person pobj = sobj;

	//2.基类对象不能赋值给派⽣类对象,这⾥会编译报错 
	sobj = pobj;

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue 3集成海康Web插件实现视频监控

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;组件封装篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来组件封装篇专栏内容:Vue 3集成海康Web插件实现视频监控 引言 最近在项目中使用了 Vue 3 结合海康Web插件来实…

Django项目创建

安装 pip install django 创建项目 首先打开powershell打开项目与创建到的文件夹 django-admin startproject django_demo01 django-admin startproject 项目名 多出了一个django_demo01的文件夹&#xff0c;这就是我们的项目了 打开项目文件夹&#xff0c;发现一个文件和…

必读推荐:掌握大模型应用的精华书籍,非常详细收藏我这一篇就够了

在这个信息爆炸的时代&#xff0c;人工智能正以前所未有的速度和规模渗透到我们生活的方方面面。其中&#xff0c;大模型应用作为 AI 领域的一大亮点&#xff0c;不仅在学术界引起广泛关注&#xff0c;更在工业界展现出巨大的应用潜力。从自然语言处理到图像识别&#xff0c;从…

最新必应Bing开户条件、流程及注意事项介绍

有效的广告推广对于企业提升品牌影响力和市场占有率至关重要。微软旗下的必应Bing搜索引擎&#xff0c;作为全球知名的搜索平台之一&#xff0c;为企业提供了精准、高效的广告推广服务。那么&#xff0c;如何在必应上开设广告账户呢&#xff1f;下面将详细介绍必应广告开户的条…

springboot 整合 快手 移动应用 授权 发布视频 小黄车

前言&#xff1a; 因快手文档混乱&#xff0c;官方社区技术交流仍有很多未解之谜&#xff0c;下面3种文档的定义先区分。 代码中的JSON相关工具均用hutool工具包 1.快手 移动双端 原生SDK 文档https://mp.kuaishou.com/platformDocs/develop/mobile-app/ios.html 2.快手 Api 开…

探索光耦:光耦——不间断电源(UPS)系统中的安全高效卫士

在现代社会&#xff0c;不间断电源&#xff08;UPS&#xff09;系统已成为保障关键设备和数据安全的关键设施&#xff0c;广泛应用于企业数据中心、家庭电子设备等场景。UPS能在电力中断或波动时提供稳定电力&#xff0c;确保设备持续运行。而在这套系统中&#xff0c;光耦&…

深入理解AQS:并发编程中的利器及其在业务场景中的应用

1. 什么是AQS&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff1f; AQS&#xff0c;全称为AbstractQueuedSynchronizer&#xff0c;是Java并发包中核心的基础框架&#xff0c;用于构建锁和同步器。它是java.util.concurrent.locks包中的基础组件&#xff0c;为多个…

屏幕画面卡住不动声音正常怎么办?电脑屏幕卡住不动解决方法

在数字时代&#xff0c;电脑作为我们日常生活与工作中不可或缺的伙伴&#xff0c;偶尔也会遇到一些小状况。其中&#xff0c;“屏幕画面卡住不动&#xff0c;但是声音依然正常”的情况就是一种常见的问题。本文将探讨这一现象的原因&#xff0c;并提供几种可能的解决方案&#…

FSCapture 9.3 | 全能截图与录屏解决方案。

FastStone Capture 是一款轻量级但功能全面的屏幕捕捉工具&#xff0c;能够轻松捕获并标注屏幕上的一切内容&#xff0c;包括窗口、对象、菜单、全屏、矩形/自由区域以及滚动窗口或网页。此外&#xff0c;它还支持录制屏幕活动、声音和网络摄像头&#xff0c;并将这些内容保存为…

[复现]比较6种股市趋势识别方

作者: Filippos Tzimopoulos 翻译整理&#xff1a;进击的小学生 文章名称: I compared 6 methods to identify the trend of the stock market. These are the results! code 与 datas &#xff0c;请转至获取&#xff01; 背景说明 通过识别市场方向&#xff0c;交易者可…

webAPI中的排他思想、自定义属性操作、节点操作(配大量案例练习)

一、排他操作 1.排他思想 如果有同一组元素&#xff0c;我们想要某一个元素实现某种样式&#xff0c;需要用到循环的排他思想算法&#xff1a; 1.所有的元素全部清除样式 2.给当前的元素设置样式 注意顺序能不能颠倒&#xff0c;首先清除全部样式&#xff0c;再设置自己当前的…

dyna批处理代码,无需蹲守,自行连续计算

用此代码即可 上面一行是模型位置 下面一行是DYNA模拟器位置 第三个框框是K文件名称 上述三者改成自己的 然后复制修改即可 复制几个就几个进行批处理

深入理解伪元素与伪类元素

在“探秘盒子浮动&#xff0c;破解高度塌陷与文字环绕难题&#xff0c;清除浮动成关键&#xff01;”中&#xff0c;我们讲到如果父盒由于各种原因未设置高度&#xff0c; 子盒的浮动会导致父盒的高度塌陷。为了解决高度塌陷的问题&#xff0c;我们可以添加伪元素。 一、伪元素…

Android 内存优化——常见内存泄露及优化方案

看到了一篇关于内存泄漏的文章后&#xff0c;就想着分享给大家&#xff0c;最后一起学习&#xff0c;一起进步&#xff1a; 如果一个无用对象&#xff08;不需要再使用的对象&#xff09;仍然被其他对象持有引用&#xff0c;造成该对象无法被系统回收&#xff0c;以致该对象在…

【element-tiptap】如何修改选中内容时的背景颜色?

前言&#xff1a;element-tiptap 用鼠标选中内容的时候&#xff0c;背景颜色跟系统设置的主题有关&#xff0c;比如的我的就是卡哇伊的pink&#xff0c;默认是淡蓝色 但是我们观察一下语雀&#xff0c;背景颜色是它规定好的颜色 这篇文章来探索一下&#xff0c;怎么自己规定选…

教学平台的智能化升级:Spring Boot应用

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

除GOF23种设计模式之简单工厂模式

文章目录 1. 简介2. 代码2.1 抽象类&#xff1a;Course.java2.2 产品A:JavaCourse.java2.3 产品B:PythonCourse.java2.4 工厂:CourseFactory.java2.5 测试&#xff1a;Test.java 3. 心得参考链接&#xff08;无&#xff09; 1. 简介 简单工厂模式(Simple Factory Patern):又称…

数据结构4——栈

1. 栈的概念及结构 栈的概念&#xff1a; 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则…

【SuperHotSwap】IDEA零配置热更新插件升级

往期往期插件v1.0.0发布的时候我发表了一篇文章&#xff0c;如下&#xff1a; 支持功能 如今插件迭代了数个版本&#xff0c;现在迎来了v1.9.0版本的重大升级。如下是支持功能。 支持功能是否支持说明MybatisXML热更新√Class热更新√增强功能需安装dcevm补丁。支持动态新增类…

git rebase的常用场景: 交互式变基, 变基和本地分支基于远端分支的变基

文章目录 作用应用场景场景一&#xff1a;交互式变基(合并同一条线上的提交记录) —— git rebase -i HEAD~2场景二&#xff1a;变基(合并分支) —— git rebase [其他分支名称]场景三&#xff1a;本地分支与远端分支的变基 作用 使git的提交记录变得更加简洁 应用场景 场景…