C++中的继承(一)

news2024/11/30 2:51:58

文章目录

  • 前言
  • 概念
  • 访问限定符
  • 基类和派生类的赋值转换
  • 继承中的作用域
  • 派生类的默认成员函数
    • 构造函数
  • 拷贝构造
    • 析构函数
  • 继承的其他一些细节

前言

我们之前说过,继承是面向对象的三大特性。

面向对象的三大特性:
封装、继承、多态。

封装在类和对象体现出。

概念

继承是什么?
继承就是一种类层次的复用,复用就是你的就变成我的.

假设我要实现一个管理系统。
如果按照以前类和对象的方式,单独去实现这个类是很坑的.

每个类都有一些信息, 有些类型之间是有一些共性,
每个类都写,那初始化每个类都要写.
在这里插入图片描述

C++创造了一个语法,可以支持继承,支持什么样的继承呢?
把我们公共的属性提取出来,放到一个类里面去,让剩下的类去继承.
在这里插入图片描述

我们也可以有些单独独立的信息.

继承是什么样的呢?
首先有很多类。如果这些类都有一些公共的特征,那我们就可以这些
类里面有些特性提取出来,专门放到一个类里面。这个类我们叫做父类。

我们想用这些特征,以前我们要写到一起,我们现在可以继承它。
怎么继承?

我们看一下它的语法:

 //基类/父类
class Person
{
public:
	void Print()
	{
		cout << "name:" << _name << endl;
		cout << "age:" << _age << endl;
	}

private:  
	string _name = "peter"; // 姓名
	int _age = 18;  // 年龄
};

class Student : public Person
{
protected:
	int _stuid; // 学号
};

继承方式有三种:
公有继承,私有继承,保护继承。

student这个类看起来啥都没有,其实里面啥都有。
在这里插入图片描述

它怎么来的?就是从它的父类。
stuent这个类的信息除了有学生的信息还有pesorn的信息,因为它继承了person.
继承也就是父类的我也有。

访问限定符

继承有三种访问限定符,但这三种访问限定符又有三种访问限定方式。
它们两两组合。
在这里插入图片描述
这些有什么规律?
它们分成了两组规则。
在这里插入图片描述
1.如果是公有成员和保护成员,就取它们继承方式和它的权限里小的那个。(公有大于保护,保护大于私有)
2.私有成员都是不可见。(不可见就是它在这个地方,你不能用)

演示一下,把父类的成员设置成私有
在子类写一个函数。
在这里插入图片描述
在这里插入图片描述
不可见就是在类里面也用不了,但是它跟私有不一样,私有在类里面可以用。

什么时候我们会定义私有呢?
这东西我不想被子类继承就用私有。

私有和保护在子类才有区别

子类能不能调用父类的函数取访问它?
可以。不可见只是指的是不能直接取访问它,取去调用父类的函数去访问也是可以的。

继承方式也可以像访问限定符一样,可以不写,class默认就是私有继承,struct默认就是公有继承。

实际当中用的最多的,就是这些。
在这里插入图片描述

基类和派生类的赋值转换

这是重点中的重点。这块想说的一个问题是什么?
在这里插入图片描述
这里会发生什么?d可以赋值给i吗?
可以。发生隐式类型转换,中间会产生临时变量,临时变量具有常性。

接着往下看,一个子类对象能不能给父类对象呢?
在这里插入图片描述
可以,但是有没有隐式类型转换的发生呢?
这里只适用于公有继承上,子类可以赋值给父类,这个过程叫做赋值兼容转换。
在这里插入图片描述
在这里插入图片描述
怎么证明呢?
在这里插入图片描述

在这里插入图片描述

子类可以赋值给父类,父类能不能给子类?
默认不可以,子类还有一些专有的属性。

继承中的作用域

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

既然它们都有独立的作用域,那基类和派生类能不能有同名成员呢?
在这里插入图片描述
派生类能不能也定义一个_num,可以。
我们c语言就规定不同的作用域可以定义同名的变量。

但是这样,我是会报错还是会访问派生类的呢?
在这里插入图片描述
理论上是访问派生类的,根据就近原则。
在这里插入图片描述
但是我就想访问基类,有没有什么办法?
指定作用域就可以了,加上域作用限定符。
在这里插入图片描述

子类和父类有同名成员,这种情况我们叫做隐藏或者重定义。
隐藏指的是默认情况下他会隐藏父类的成员。

class Person
{
protected:
	string _name = "小李子"; // 姓名
	int _num = 111; 		// 身份证号
};

class Student : public Person
{
public:
	void Print()
	{
		cout << Person::_num << endl;
		cout << _num << endl;
	}

protected:
	int _num = 999; // 学号
};

这里有个很坑的东西,经常出选择题考。
以下程序哪个是对的。
在这里插入图片描述
这道题的杀手锏是A,为什么是A?
函数名相同,参数不同构成函数重载。
那现在有一个问题,vector里的push_back和list里的push_back呢?
记住,函数重载必须在同一个作用域里面。

编译也没有报错。
虽然它们参数不同,但是它们的关系确实是隐藏。

最麻烦的考法是这样的。
下面这个选什么。
在这里插入图片描述
这道题如果是不定向选择,那就是BC.
如果确实要访问A里的fun, 要指定一下作用域

b.A::func();

结论:
如果是成员函数的隐藏,只需要函数名相同就可以构成隐藏。
不需要考虑参数,不需要考虑返回值。

注意在实际中最好不要定义同名的成员,不然自己坑自己。

派生类的默认成员函数

构造函数

派生类的构造函数时怎么玩的呢?
跟我们以前学的有一点点不一样。
在这里插入图片描述

在这里插入图片描述
注意看这个派生类,我什么都没有写.发生了啥?
如果我们不写,子类会自动调用父类的成员。

如果我们写了呢?
在这里插入图片描述
在这里插入图片描述
不可以。为什么呢?

在派生类当中,规定了,父类的成员,必须调父类的构造函数初始化。
你不写它也会调用父类的,你写他也会调用父类的。
在这里插入图片描述
在这里插入图片描述
上面两个都可以编译通过。
你不写他也会调用父类的默认构造,在初始化列表里调。
继承就像子类把父类当作一个自定义类型的整体成员一样。

那如果父类没有默认构造怎么办?
那我们就必须自己写了,自己显示的调用了。

拷贝构造

拷贝构造和前面也是同样的道理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以,但是你自己不写他会不会调用父类的拷贝构造。
不会,要初始化父类怎么办?调用父类的拷贝构造。但是要求调用父类的拷贝构造,
是不是要传一个父类的对象过去。

只有子类对象没有父类对象,如何把子类对象父类这一部分拿出来啊。
我们可以用我们之前讲到的切片。
在这里插入图片描述
子类对象我也没有父类的那一部分,但是我可以传过去让它自己切就可以了。
在这里插入图片描述

这里回答一下之前遗留下来的一个问题?
如果是子类对象给父类对象,这个地方是怎么给过去的?
在这里插入图片描述
是memcpy拷贝过去还是怎么拷贝。
这里还是调用了拷贝构造,调用了父类的拷贝构造。
在这里插入图片描述
operatro=也是一样的道理
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
但是这里出现了一个栈溢出的问题,是怎么回事呢?
栈溢出一般都是重复调用,这里教大家一个技巧,可以看调用堆栈
在这里插入图片描述
死循环了。为什么?
因为Student类里面的operator=和Person类里面的operator构成隐藏关系。
所以这里自己调用自己了。
在这里插入图片描述
指定作用域就可以了
在这里插入图片描述

在这里插入图片描述

总结一下就是自己干自己的,父类处理父类的。

可不可以不写拷贝构造和赋值呢?
可以,我们之前说过,拷贝构造针对内置类型进行值拷贝或者浅拷贝,
针对自定义类型会调用它的拷贝构造。

析构函数

特点都是先父后子
在这里插入图片描述

在这里插入图片描述

但是有个非常奇怪的现象,我们调用不了析构。为什么?
由于以后多态的原因,析构不会用这个名字,
析构函数会被处理成Destructro,所以它们会构成隐藏的关系。
所以还是指定一下。
在这里插入图片描述
但是这样也不行,父类的析构被调用了两次。
在这里插入图片描述
其它成员函数都可以显示调用,唯独析构函数我们不要显示调用。
它可以自动调用,为什么它可以自动?以为它要保证我们的顺序。
在这里插入图片描述
自己显示写不能保证调用先子后父的顺序。

为什么要先析构子类再析构父类?
因为父类先定义,子类后定义。

先析构父类,再析构子类有可能会出现野指针的问题。
在这里插入图片描述

继承的其他一些细节

友元关系不能被继承。
比如一个类,一个函数是你父类的友元,那是不是你子类的友元呢?
不是。
在这里插入图片描述
但是我就是想访问怎么办?
再定义一个友元就可以了。

class Person
{
public:
	friend void Display(const Person& p, const Student& s);
//protected:
	string _name; // 姓名
};
class Student : public Person
{
	friend void Display(const Person& p, const Student& s);
protected:
	int _stuNum; // 学号
};

void Display(const Person& p, const Student& s)
{
	cout << p._name << endl;
	cout << s._stuNum << endl;
}

void main()
{
	Person p;
	Student s;
	Display(p, s);
}

静态成员是怎么走的?
在这里插入图片描述
在这里插入图片描述

父类继承有一个_count,子类继承会不会也友一个_count呢?
不会。但是从域的角度,子类可以访问它。

无论你继承多少次,都只有一个_count
静态成员变量属于整个类,它不仅属于父类也属于子类。但是只有同一个。

证明一下:
父类当中的_name和子类当中的_name是不是同一个。
不是,它们的地址是不一样的。
但是_count是同一个。

把父类protected:去掉
在这里插入图片描述

下一个问题,这里Peron或者以Peson为继承的子类对象总共创建了多少个对象?
怎么算呢?这里有一个非常巧妙的东西。在父类的构造函数++_count就可以,为什么?
因为子类对象必须调用父类对象去初始化
在这里插入图片描述>

静态的成员所有继承的派生类共享。

实现一个不能被继承的类,如何实现?
最简单的方式就是把它的构造函数私有化,或者析构函数私有化。为什么?
因为构造函数私有了,继承了以后创建不了对象,为什么?
因为子类的构造函数必须去调用父类的构造函数,而父类的构造函数私有,子类调用不了。
在这里插入图片描述
A的构造函数私有,B是无论如何也调用不了。
A怎么调用呢?A是有办法的。

class A
{
public:
	static A CreateObj()
	{
		return A();
	}
private:
	A()
	{}
};
class B : public A
{};
int main()
{
//要调用函数首先要创建对象
//我们可以用静态成员函数,就可以直接用类去调用它
	A::CreateObj();
	return 0;
}

友元是能不用就不用。

其实C++正常的继承学到这里也差不多了,但是还有一个大坑,我们留到下篇文章

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

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

相关文章

大一python题库刷题训练,大一python填空题题库

大家好&#xff0c;给大家分享一下大一python题库及答案和分析&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 这篇文章主要介绍了大一python上机题库及答案&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完…

【线性代数】期末速通!

1. 行列式的性质 1.1 求一个行列式的值 特殊地&#xff0c;对角线左下全为0&#xff0c;结果为对角线乘积。行 r 列 c 1.2 性质 某行&#xff08;列&#xff09;加上或减去另一行&#xff08;列&#xff09;的几倍&#xff0c;行列式不变某行&#xff08;列&#xff09;乘 …

智能优化算法应用:基于海洋捕食者算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于海洋捕食者算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于海洋捕食者算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.海洋捕食者算法4.实验参数设定5.算法…

git-lfs基本知识讲解

目录 1. 基本知识2. 安装 1. 基本知识 git-lfs 是 Git Large File Storage 的缩写&#xff0c;是 Git 的一个扩展&#xff0c;用于处理大文件的版本控制。 它允许你有效地管理和存储大型二进制文件&#xff0c;而不会使 Git 仓库变得过大和不稳定。以下是一些与 git-lfs 相关…

mysql原理--InnoDB的表空间

1.概述 通过前边儿的内容大家知道&#xff0c; 表空间 是一个抽象的概念。 对于系统表空间来说&#xff0c;对应着文件系统中一个或多个实际文件&#xff1b;对于每个独立表空间来说&#xff0c;对应着文件系统中一个名为 表名.ibd 的实际文件。可以把表空间想象成被切分为许许…

仿易订货的订货系统源码一般多少钱

易订货是一款面向中小企业的B2B电子商务平台&#xff0c;旨在提供一站式的采购和销售解决方案。不少批发商贸企业在数字化转型的时候会采用订货系统&#xff0c;今天我们谈谈仿易订货的订货系统源码需要多少钱。 这款订货系统是一款SaaS&#xff0c;所以它是不面向市场销售源码…

Java 第9章 房屋出租系统

设计 如图是系统的分层结构&#xff0c;包括了界面层、业务层和数据层。 单独建包&#xff1a;由于在实际开发过程中&#xff0c;可能会出现管理多个界面的情况&#xff0c;所以界面需要单独建包&#xff0c;其他同理。 开发任务&#xff1a;从界面层深入到业务层&#xff0c…

ce从初阶到大牛--函数

1、显示/etc/passwd文件中以bash结尾的行&#xff1b; grep "bash$" /etc/passwd2、找出/etc/passwd文件中的三位或四位数&#xff1b; grep -E \b[0-9]{3,4}\b /etc/passwd3、找出/etc/grub2.cfg文件中&#xff0c;以至少一个空白字符开头&#xff0c;后面又跟了非…

产品定位后选择通过外包团队降低成本:迅腾文化的优势与实践

产品定位后选择通过外包团队降低成本&#xff1a;迅腾文化的优势与实践 在激烈的市场竞争中&#xff0c;产品定位是企业成功的关键。然而&#xff0c;仅凭优秀的产品定位并不足以确保企业的成功&#xff0c;如何在降低成本的同时保持产品质量和市场竞争力也是至关重要的。在这…

计算机网络:DNS域名解析系统

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

【TB作品】51单片机,语音出租车计价器

西交大题目 1.语音出租车计价器 一、功能要求: 1.具有可模拟出租车车轮转速传感器的硬件设计,可计量出租车所走的公 里数。 2.显示和语音播报里程、价格和等待红灯或堵车的计时价格: 3.具有等待计时功能 4.具有实时年月日显示和切换功能。 5.操作简单、界面友好。 二、设计建议…

委托线程安全

委托线程安全是指将对共享数据的访问委托给线程安全的类&#xff0c;从而避免在调用方代码中进行额外的同步控制。这可以通过将线程安全性限定在一个类内部来实现。以下是一个简单的例子&#xff1a; 假设有一个计数器类 Counter&#xff0c;它不是线程安全的。 public class…

数据手册Datasheet解读-MOS管笔记

数据手册Datasheet解读-MOS管笔记 NMOS应用场景一般特征第一个参数Vdss第二、三个参数Rds&#xff08;on&#xff09;、IdMOS管的散热绝对最大额定值第一个参数-Vd第二个参数-Vdgr第三个参数-Vg(栅源电压)第四个参数-Id第五个参数-Idm第六个参数-Ptot第七个参数-Viso第七和八的…

【合成数字】合成类游戏-uniapp项目开发流程详解

以前玩过2048游戏&#xff0c;从中发现规律&#xff0c;想到跟合成类游戏相似&#xff0c;知道为什么很相似吗&#xff0c;在这里&#xff0c;做一个数字合成游戏玩玩吧&#xff0c;感兴趣的话可以看看&#xff0c;这里给大家讲一讲数字合成游戏的开发过程。 文章目录 创建项目…

四. 基于环视Camera的BEV感知算法-BEVDet

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Cam…

【Java】智慧工地系统:让建筑行业管理更简单

概述 智慧工地管理平台面向房建、能源、交通各类工地的管理者&#xff0c;通过AI视频、物联感知技术对工地场景中的施工机械、建筑材料、施工规范、施工环境监管、完善施工现场项目管控。实现项目管控、特种设备管理、绿色施工、工地巡检等业务功能&#xff0c;沉淀工地监管数…

6.鸿蒙app_hap_DevEco如何真机调试模式_app安装在手机中

真机调试 手机》设置》关于手机》HarmonyOS版本》软件版本&#xff0c;连续单击10次启动开发者模式 然后&#xff1a;设置》系统和更新》开发人员选项》打开USB调试功能。 电脑USB连接手机&#xff0c;手机USB连接类型&#xff0c;传文件&#xff08;不要选择仅充电&#xf…

CAD 审图意见的导出

看图的时候喜欢在图上直接标注意见&#xff0c;但是如果还要再把意见一行一行的导出到word里面就很麻烦&#xff0c;在网上看了一个审图软件&#xff0c;报价要980&#xff0c;而且那个审图意见做的太复杂了。 我的需求就是把图上标的单行文字和多行文字直接导出来就行&#x…

MybatisPlus进阶,UUID VS SnowFlake(雪花算法)

目录 一、什么是MybatisPlus 为什么要学MybatisPlus&#xff1f; 特性&#xff1a; 二、快速入门 2.1快速初始化一个空的spring boot 项目 2.2配置依赖 2.3配置(连接数据库) 2.4在spring boot启动类中添加MapperScan注解&#xff0c;扫描Mapper文件夹&#xff1a; 2.5…

自动驾驶学习笔记(二十)——Planning算法

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo 社区开发者圆桌会》免费报名—>传送门 文章目录 前言 参考线平滑 双层状态机 EM Planner …