【C++】继承(上)

news2024/9/23 7:40:33

在这里插入图片描述

个人主页~


继承

  • 一、继承的概念以及定义
    • 1、继承的概念
    • 2、继承的定义
      • (1)定义格式
      • (2)继承基类成员访问方式的变化
  • 二、基类和派生类对象赋值转换
  • 三、继承中的作用域

一、继承的概念以及定义

1、继承的概念

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

以前我们接触过的使代码可以复用的一种手段就是封装函数,比如有三个函数都需要交换函数,我们把交换函数封装在外边,然后在写这三个函数的时候直接调用交换函数就可以了

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

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

class Teacher : public Person
{
protected:
	int _job_id; // 工号
};

void test1()
{
	Student s;
	Teacher t;
	s.Print();
	t.Print();
}

在这里插入图片描述
这是一个简单的用了继承的代码,Person对于Student和Teacher来说是一个父类(基类),Student和Teacher就是子类(派生类),继承之后父类的成员都会成为子类的一部分

我们来看调试过程,这就是调用Print函数的前后两步,通过调试窗口我们很清楚地看到这里Student类的Print直接复用Person类的Print
在这里插入图片描述
在这里插入图片描述

2、继承的定义

(1)定义格式

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

Student:派生类(子类)

public:继承方式,包括public、protected、private

Person:基类(父类)

我们发现继承方式有三种,和访问限定符的三种是一样的

(2)继承基类成员访问方式的变化

类成员/继承方式public继承protected继承private继承
基类的public成员派生类的public成员派生类的protected成员派生类的private成员
基类的protected成员派生类的protected成员派生类的protected成员派生类的private成员
基类的private成员派生类中不可见派生类中不可见派生类中不可见

总结:

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

基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected,可以看出保护成员限定符是因继承才出现的,我们之前学习的过程中说protected和private是等价的,但在学习继承后,我们就知道它们的区别了

在看完表格后我们发现一个规律,对于可见性来说public>protected>private,除了基类的private成员在派生类中不可见以外,其他所有的继承,都是取继承方式与访问限定符中可见性较小的那一个作为派生类的访问限定符

使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式

实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强,也就是说上面的表格内容不要死记硬背,现实场景下真正用到的没有那么多,按照上面的规律来记忆就可以

class Person
{
public:
	void Print()
	{
		cout << _name << endl;
	}
protected:
	string _name; // 姓名
private:
	int _age; // 年龄
};
//class Student : protected Person
//class Student : private Person
class Student : public Person
{
protected:
	int _stu_id; // 学号
};

像是如上代码,在继承方式为public时,Person当中的Print为public可以在派生类内外调用,_name为protected可以在派生类内调用,_age在派生类内不可见

在继承方式为protected时,Person当中的Print为protected可以在派生类内调用,_name为protected可以在派生类内调用,_age在派生类内不可见

在继承方式为private时,Person当中的三个成员在派生类内都不可见

二、基类和派生类对象赋值转换

派生类对象可以赋值给基类的对象、基类的指针、基类的引用,我们把它叫做切割,因为一般来说派生类的成员包括但不限于基类的成员,将除了基类以外的成员切割掉然后赋值给基类就叫切割

基类对象不能赋值给派生类

基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用,但是必须是基类的指针是指向派生类对象时才是安全的,这部分我们在多态的内容中会详细介绍

这里我们复习一个内容,就是前面讲的临时变量具有常性

double d = 1.1;
int i = d;

这里我们看到,当二者的类型不相同时,第二句代码不是d直接给到i,而是d产生一个临时变量,然后由这个临时变量给到i
在这里插入图片描述
我们看到i是不能直接做d的别名的,而加一个const修饰就可以取到别名,这就是临时变量具有常性的证明
在这里插入图片描述
不管是什么类型的常性变量,我们都要加const修饰以后才能引用它
在这里插入图片描述
在这里插入图片描述
但是看如下的情况
在这里插入图片描述
这是没有任何问题的,因为子类对象赋值给父类对象、父类指针、父类的引用被认为是天然的,中间不产生临时对象,这叫做父子类赋值兼容规则(切割)

class Person
{
protected:
    string _name; // 姓名
    string _sex;  // 性别
    int _age; // 年龄
};
class Student : public Person
{
public:
    int _stu_id; // 学号
};
void Test()
{
    Student stu;
    // 1.子类对象可以赋值给父类对象/指针/引用
    Person per = stu;
    Person* pp = &stu;
    Person& rp = stu;

    //2.基类对象不能赋值给派生类对象
    //sobj = pobj;

    // 3.基类的指针可以通过强制类型转换赋值给派生类的指针
    pp = &stu;
    Student * ps1 = (Student*)pp; // 这种情况转换时可以的
    ps1->_stu_id = 10;

    //pp = &per;
    //Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问题
    //ps2->_stu_id = 10;
}

这里上面的代码都比较容易理解,下边这一块,也就是基类的指针可以通过强制类型转换赋值给派生类的指针这里,分了两种状况

上面这种可以是因为stu本身就是Student类型,所以ps1指向的实际上是stu的起始地址,这是合法的,因此可以安全地通过ps1访问_stu_id成员

下面这种不可以是因为per并非Student类型,所以pp并不指向一个包含_stu_id成员的Student对象,当通过ps2访问_stu_id时,实际上是在访问per对象的内存,但是按照Student的布局来解释这块内存,这可能导致越界访问、未定义行为,或者程序崩溃

三、继承中的作用域

在继承体系中基类和派生类都有独立的作用域

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

需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏

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

class Person
{
protected:
    string _name = "little_monster"; // 姓名
    int _id = 111;   // 身份证号
};
class Student : public Person
{
public:
    void Print()
    {
        cout << " name:" << _name << endl;
        cout << " id:" << Person::_id << endl;
        cout << " stu_id:" << _id << endl;
    }
protected:
    int _id = 999; // 学号
};
void Test()
{
    Student s1;
    s1.Print();
};

在这里插入图片描述
可以看到我们直接调用_id的话打印的是Student类中的_id,这就是成员函数的隐藏,当我们想要调用Person类的_id时,就常规调用Person::_id 就可以了

当然这不只是变量,函数在重名时也会发生成员函数的隐藏,我们遵循就近原则,而且基类与派生类成员函数重名时不构成函数重载而是隐藏


今日分享就到这了~

在这里插入图片描述

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

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

相关文章

【C语言零基础入门篇 - 17】:排序算法

文章目录 排序算法排序的基本概念冒泡排序选择排序插入排序 排序算法 排序的基本概念 1、什么是排序&#xff1f; 排序是指把一组数据以某种关系&#xff08;递增或递减&#xff09;按顺序排列起来的一种算法。 例如&#xff1a;数列 8、3、5、6、2、9、1、0、4、7 递增排序…

Windows 配置docker和ubuntu系统

windos10 配置docke时&#xff0c;无意间发现wsl功能挺好用&#xff0c;而且是和docker 的linux容器连通的。 记录一下解决的几个问题 error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/images/json: open //./pipe/docker_engine: The system cannot …

音乐项目,总结

今天的写的思路都挺简单的但是比较繁琐&#xff0c;这个查找&#xff0c;传文件的话可以了&#xff0c;但是没有用分片传送&#xff0c;然后在写音乐播放的处理&#xff0c;<歌单&#xff0c;二级评论&#xff0c;歌曲歌词滚轮播放>三个还没有实现&#xff0c;时间挺紧张…

Spring 源码分析

Spring 源码版本 4.2.8.RELEASE Bean 生命周期 动态代理 代理模式 优点: 在不修改目标对象的功能前提下&#xff0c;能通过代理对象对目标功能扩展缺点: 代理对象需要与目标对象实现一样的接口&#xff0c;所以会有很多代理类&#xff0c;一旦接口增加方法&#xff0c;目标对…

HarmonyOS鸿蒙开发实战(5.0)悬浮窗拖拽和吸附动画实践

鸿蒙HarmonyOS NEXT开发实战往期文章必看&#xff08;持续更新......&#xff09; HarmonyOS NEXT应用开发性能实践总结 HarmonyOS NEXT应用开发案例实践总结合集 最新版&#xff01;“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门…

spring揭秘22-springmvc01-概述

文章目录 【README】【1】MVC模式实现web应用架构【1.1】MVC模式【1.2】单个集中式控制器实现【1.2.1】引入2层控制器 【2】springmvc概述【2.1】一级控制器&#xff1a;DispatcherServlet【2.1.1】HandlerMapping处理器映射【2.1.2】springmvc二级控制器Controller【2.1.3】Vi…

【自动驾驶】控制算法(十)深度解析车辆纵向控制 | Carsim 油门刹车标定表的制作

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

7款国内AI搜索引擎大全网站

与传统搜索引擎相比&#xff0c;AI搜索引擎利用先进的自然语言处理、机器学习和深度学习技术&#xff0c;提供更加精准和个性化的搜索服务。小编就来和大家分享国内免费的AI搜索引擎网站&#xff0c;方便大家体验使用。 AI搜索引擎网站大全&#xff1a;https://www.bgrdh.com/f…

java日志框架之Log4j

文章目录 一、Log4j简介二、Log4j组件介绍1、Loggers (日志记录器)2、Appenders&#xff08;输出控制器&#xff09;3、Layout&#xff08;日志格式化器&#xff09; 三、Log4j快速入门四、Log4j自定义配置文件输出日志1、输出到控制台2、输出到文件3、输出到数据库 五、Log4j自…

ESP32无线WiFi蓝牙SOC,设备物联网通信方案,启明云端乐鑫代理商

在当今数字化时代&#xff0c;物联网(IoT)正迅速成为连接我们生活各个方面的无形纽带&#xff0c;越来越多的日常物品被赋予了智能功能&#xff0c;从灯泡到插座&#xff0c;从门锁到家电设备&#xff0c;这些设备正在改变我们与家庭环境的互动方式。 随着智能产品的普及&…

*C++:string

一.STL简介 1.STL STL(standard template libaray- 标准模板库 ) &#xff1a; 是 C 标准库的重要组成部分 &#xff0c;不仅是一个可复用的组件库&#xff0c;而且 是一个包罗数据结构与算法的软件框架 。 2.STL六大组件 二.标准库里的string类 标准string库网址&#xff1…

【AI算法岗面试八股面经【超全整理】——NLP】

AI算法岗面试八股面经【超全整理】 概率论【AI算法岗面试八股面经【超全整理】——概率论】信息论【AI算法岗面试八股面经【超全整理】——信息论】机器学习【AI算法岗面试八股面经【超全整理】——机器学习】深度学习【AI算法岗面试八股面经【超全整理】——深度学习】NLP【A…

Crack道路裂缝检测数据集——目标检测数据集

【Crack道路裂缝检测数据集】共3684张。 目标检测数据集&#xff0c;标注文件为YOLO适用的txt格式。已划分为训练、验证集。 图片分辨率&#xff1a;224*224 类别&#xff1a;crack Crack道路裂缝检测数据集 数据集描述 该数据集是一个专门用于训练和评估基于YOLO&#xff0…

[笔记]某变频器,功能列表及参数表

产品代号&#xff1a;INVT GOODDRIVE&#xff0c;这家公司我的产品我似乎在特检院看到过&#xff1f;或者在某个地铁建设工地看到过。是深圳的。 1.产品功能点&#xff1a; 变频锥形电机控制、抱闸转矩验证&#xff1f;抱闸反馈零位检测行程限位超载防护轻载升速&#xff08;…

机器学习课程学习周报十三

机器学习课程学习周报十三 文章目录 机器学习课程学习周报十三摘要Abstract一、机器学习部分1. 文生图模型概述2. Stable Diffusion概述3. ControlNet概述4. 概率论复习&#xff08;二&#xff09; 总结 摘要 本周的学习内容涵盖了文生图模型、Stable Diffusion、ControlNet以…

从零开始讲DDR(5)——读懂Datasheet

对于开发人员来说&#xff0c;需要根据实际场景和使用的需要&#xff0c;使用不同厂家&#xff0c;不同型号的DDR&#xff0c;虽然原理上大同小异&#xff0c;但是还是有一些细节上的需要注意的地方&#xff0c;接触一个新的DDR芯片&#xff0c;首先就是需要找到对应的datashee…

Mybatis 返回 Map 对象

一、场景介绍 假设有如下一张学生表&#xff1a; CREATE TABLE student (id int NOT NULL AUTO_INCREMENT COMMENT 主键,name varchar(100) NOT NULL COMMENT 姓名,gender varchar(10) NOT NULL COMMENT 性别,grade int NOT NULL COMMENT 年级,PRIMARY KEY (id) ) ENGINEInnoD…

LeetCode讲解篇之238. 除自身以外数组的乘积

文章目录 题目描述题解思路题解代码 题目描述 题解思路 对于该题&#xff0c;我们可以先使用一个循环记录所有非零元素的乘积结果和非零元素的个数 如果非零元素个数为0&#xff0c;则非零元素的乘积除以数组对应位置的数字就是除自身以外的数组的乘积如果非零元素个数为1&am…

新质农业——水肥一体化技术

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案&#xff0c;帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、埃域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&…

【人工智能学习】8_人工智能其他通用技术

知识图谱 在看影视剧或小说时&#xff0c;若其中的人物很多、人物关系复杂&#xff0c;我们一般会用画人物关系图谱来辅助理解人物关系。那什么是知识图谱呢&#xff1f; 知识是人类对信息进行处理之后的认识和理解&#xff1b;对数据和信息的凝练、总结后的成果。 将信息转…