当前位置: 首页 > news >正文

C++11:继承

目录

继承的基本概念

继承方式

 基类和派生类对象赋值转换/切片

继承中的作用域

派生类的四个成员函数:

 构造函数

拷贝构造函数

赋值重载

析构函数

静态成员

继承与友元

多继承

菱形继承

多继承的指针偏移问题

 组合


继承的基本概念

继承出现的契机是某一些类中会有一部分相似的信息,我们希望以这个类的基本信息为基础能生成更多高分化的类。

集体来讲就是具有一些公共属性的类我们不希望多次去写,比如说人们的职位分布,其主要重合的信息比如名字电话号码性别等等

具体的操作流程如下,我们创建一个叫Person的类,然后使用public的继承方式将其继承到worker这个子类上

当然继承的术语还有其他叫法,不过都一样,喜欢哪个用哪个

继承的使用格式:

 子类会会继承获得父类的成员变量以及成员函数

好,既然牵扯到了访问限定符的问题,那么对于子类,它的访问方式是怎么做的呢?或者说它的访问规则是怎么样的?

继承方式

 

由于访问限定符和继承方式33相乘,有9种继承方式,不过说明白还是比较简单的

基类中的私有其本意是:“我不想给你继承”,我们调试看看

  • 诶?不对啊,不是说不可见吗,这不还是继承下来了吗?这里造成误解的原因则是关于“不可见”的定义问题,虽然private修饰的成员变量是不可见的,但此处的不可见则是指于子类中,无论是类内部还是外部都不能访问这个继承下来的变量。继承是继承下来了,但是它上了层盾,你没法访问。

但是这里还是很奇怪,我为什么还是能借助父类的函数访问到不可见的变量?

 这里的做法确实没有什么问题,但是如果我们想在子类去访问就不行了。

那么有没有比较中立一点的?protect就可以实现比private宽容一点的访问权限,也就是类外部依旧不能访问,但是类内部可以。

我们在protect下创建一个新的成员变量,然后在派生类的成员函数中去访问它。

那么上面的情况都是在public的条件下派生类继承基类时的权限问题,那么当我们更换继承方式的时候是什么样的?

当我们使用Protect的方式访问时,位于public下的函数不能使用了,但是protect内部的依然可以private依旧不行

由于重复内容比较多,就借用一下表格了。

总结起来:

  • 当以public方式继承时,子类可以访问到父类public下的成员函数以及成员变量,也可以访问到portected下的变量和函数,private不行。
  • 当以protected方式继承时,子类不能访问到父类访public下的成员函数以及成员变量,但可以访问到portected下的变量和函数,private不行。
  • 当以protected方式继承时,子类不能访问到父类访public下的成员函数以及成员变量,依然可以访问到portected下的变量和函数,private不行。

需要注意的是:访问限定符可以不写

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

在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强

 总结继承的实用性:继承的这个复用功能如果去细品会发现它还是能节省不少工作流程的,我们仅需要一个主体框架,当我们需要以这个框架为基础生成更加多功能的组件或者说类的时候,复用就会变得方便许多,毕竟我们不需要再回头去改类内部的成员变量函数什么的。

 基类和派生类对象赋值转换/切片

 既然使用了继承,那么子类一般情况下一定会比父类多一点成员变量什么的,在这种情况下假如将子类赋值回给父类生成的对象,父类的引用,父类的指针时,就会产生一个类似切片的过程

 非常形象,子类对象反赋值回父类对象直接将子类对象中多余的部分切去,保留对应的父类成员变量。

注意!在这个过程中没有类型转换!也没有临时对象,根据我们之前学习的内容,两个不同类型的类是不能相互赋值的,能发生类型转换的是单参构造函数虽然可以发生,在这个过程中,单一变量被拿去构造了一个相同类型的临时对象,这个临时对象去赋值给新的对象。

而且仅针对子类向上赋值给父类,不能父类给子类。

所以这个赋值的过程是不会生成临时变量的。

那么看上去也没什么影响嘛!不就是少了个临时对象么?

临时对象其实在很多方面会比较碍事,比如如下,我们想引用一下这个j,但是其中产生的临时变量具有常性,所以不行,加个const才行。

举个例子:

 而父类子类这个过程就不需要考虑了,直接爽用

但是也是有代价的,赋值或者引用发生时,它仅生效于父类子类相同的那一部分

而且继承赋值时,会调用父类的拷贝构造函数

继承中的作用域

 有个小问题,当我们的子类和父类中都有一个同名的变量时,访问哪一个?

在子类访问用子类的,父类访问用父类的

当然想要在子类访问父类的也不是不行,加个作用于限定符即可。

其实发生这种现象的原因是当出现同名对象时,子类会隐藏父类的同名成员,但不是不让访问

那么刚才是同名的成员变量,那么假如现在是同名成员函数会怎么处理?

首先一定会触发隐藏,跟同名的成员变量没什么区别。

但是如果它写成重载的样式呢??刁钻的老6就来了。

那么它们构成重载还是重写呢?还是隐藏(重定义)或者编译报错?

  • 首先,重载的发生条件是处于同一作用域下才会重载。
  • 那么他就不是能重载的,如下这样使用时就是单纯的隐藏。

 以函数调用为举证,当前的Text需要传参

 构成了隐藏,没法调到A的函数,被隐藏了要加作用域限定符才是。

派生类的四个成员函数:

 既然派生类类会继承基类的对象,那么它里面的各个成员函数的工作则是不同的。

 构造函数

  • 不同于我们创建一个新的对象,对于派生类来说,基类的对象派生类只能去调用基类的构造函数才能初始化,同理,假如基类对象其中有需要被清理的资源也只能调用父类的析构函数
  • 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认
  • 的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。

我们就尝试初始化一下基类的对象

  •  但是想要去初始化它是不可以通过直接访问的方式来进行的,要调用基类的构造函数才行。

 调用父类的构造函数

拷贝构造函数

  •  拷贝构造也是同理,基类的对象需要调用基类的拷贝构造来拷贝,派生类的则是处理自己的对象。派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化
     

 当然,我们也可以借助切片的行为来实现拷贝构造,切片的行为会自己调用父类的拷贝构造函数。

赋值重载

子类的和父类构成隐藏,派生类的operator=必须要调用基类的operator=完成基类的复制

析构函数

已我们前面的理解,既然构造等默认成员函数们都是以各自管各自类的工作方法执行它们的功能,那么析构函数也应该是子类析构自己的,然后调用父类的析构去析构父类成员。

但是析构函数有个让人不解的点:为什么没办法调用父类的构造?

 这样就可以了

 

 为什么加了个作用域就可以了?

  • 因为子类析构函数和父类析构函数构成了隐藏关系(由于后面多态的关系需求,所有的析构函数都会被特殊处理成为相同名字的函数,然后构成隐藏)

但是还有一个及其奇怪的点,为什么我们在指定作用域只调用了一次父类的析构函数,结果调用了两次父类的析构函数?甚至还崩溃了。

继承结构下的析构函数的特点:因为子类的析构函数会自己默认调用父类的析构函数

  • 子类的析构函数和父类的析构函数默认情况下会构成隐藏关系,从调用角度来讲,我们没法直接调用到基类的析构函数来析构基类的对象。(回顾一下:函数名相同时构成隐藏)但这根本名字不一样啊?原因就是为了多态而服务的,因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同。那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系,这个问题要先遗留上一阵子了。

所以总结一下,子类的默认成员函数,构造和赋值都要显示调用,而析构则不用


做个小题目巩固以下知识吧!

下面说法正确的是( )

A.派生类构造函数初始化列表的位置必须显式调用基类的构造函数,已完成基类部分成员的初始化

B.派生类构造函数先初始化子类成员,再初始化基类成员

C.派生类析构函数不会自动析构基类部分成员

D.子类构造函数的定义有时需要参考基类构造函数

 


答案以及解析:

A.如果父类有默认构造函数,此时就不需要

B.顺序相反,先初始化父类,再是子类

C.会调用,并且按照构造的相反顺序进行调用

D.是的,需要看父类构造函数是否需要参数子类的,从而你决定子类构造函数的定义

静态成员

  • 当继承发生时,其静态成员还是同一个,而非静态成员则是各自的。
  • 究其原因,静态成员是属于整个类中所有的对象,同时也属于所有的派生类。

继承与友元

  •  友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
     

多继承

在继承的方法后面加上一个逗号就可以实现多继承

 

 比如说一个市民,它可以复用一个人类,然后再复用一个工人类,这其实还不错,但是非常阴间的玩意马上就来了,菱形继承

菱形继承

 

 

菱形继承会造成数据冗余以及二义性

  • 以二义性为例:以上的这个例子,相当于不仅继承了strudent的Person类,又继承了Teacher的Person类,假如我们直接去访问基类中的对象时,会直接报错,因为编译器也不知道你想访问那个Person类里头的对象。

我们构建一个简单的菱形继承,然后在内存中观察一下它真实的空间分配

 

 

  • 我们在内存之中看到了菱形继承的大致模型,这个模型本身并不复杂,而且非常直观,BC两个对象之中都各有一个a成员,他们是各自独立开来的。
  • 那么当我不想要独立开这个a的时候该怎么办呢?接下来的情况就有些复杂,我们对中介类加上一个virtual

 

  • 我们发现,a此时没有独立开来,而是算作了整个菱形继承的公共对象,无论在哪更改a,都指向了单独的一个a,而非独立开来的a。
  • 那么问题来了,原本的a的地址变成了什么?

 我们发现在内存中他们的字节数都是一样的,这个其实就是距离虚基类对象的偏移量

 这种记载偏移量的方法可以直接让我们使用菱形继承的时候编译器可以非常精确的寻找到当前基对象的位置并更改以解决二义性的问题。

多继承的指针偏移问题

多继承时,一个继承了多个类的对象在使用其中一个父类指针产生切片时,可能会发生指针偏移

借助一道题可以很好的理解这个问题

 那么P1 P2 的指向模型如下

 

 组合

 什么是组合?

 以上图为例,就是在一个类里面已某个自定义类型再创建了一个对象

  • 他和继承都是可以实现复用的,但是相较于继承,组合不能使用父类被保护的成员,
  • 那么有人提出了一个概念,继承称之为:白箱复用,而组合则叫做:黑箱复用
  • 黑和白的区别主要还是区别于能不能看见其中一些内部的使用方法。
  • 平常来讲,组合的效果会更加好,因为黑箱复用的耦合度较低。
  • 耦合度指的是关联互相影响度,牵连的东西的多少。
  • 我们以继承为例,由于是白箱复用,当我们更改父类内部的成员时,其子类绝对会受到影响,而对于组合来说则不会,毕竟没有对你门洞大开,其耦合度低,基本上影响不到组合的对象。

 

以上就是C++继承中部分的知识了

相关文章:

C++11:继承

目录 继承的基本概念 继承方式 基类和派生类对象赋值转换/切片 继承中的作用域 派生类的四个成员函数: 构造函数 拷贝构造函数 赋值重载 析构函数 静态成员 继承与友元 多继承 菱形继承 多继承的指针偏移问题 组合 继承的基本概念 继承出现的契机是某一…...

【蓝桥杯试题】递归实现排列型枚举

💃🏼 本人简介:男 👶🏼 年龄:18 🤞 作者:那就叫我亮亮叭 📕 专栏:蓝桥杯试题 文章目录1. 题目描述2. 代码展示法一:dfs法二:next_perm…...

入职字节测试岗外包一个月,我离职了...

有一种打工人的羡慕,叫做“大厂”。真是年少不知大厂香,错把青春插稻秧。但是,在深圳有一群比大厂员工更庞大的群体,他们顶着大厂的“名”,做着大厂的工作,还可以享受大厂的伙食,却没有大厂的“…...

weak学习入门-01

作用:集中在特征提取、算法选择和参数调优上 本篇几乎是汇总了大佬的参考 官网https://www.cs.waikato.ac.nz/ml/weka 大佬的入门教程:初试weka数据挖掘 - 加拿大小哥哥 - 博客园 (cnblogs.com) 参考书:数据挖掘实用机器学习技术(原书第2版)...

线程池中shutdown()和shutdownNow()方法的区别

线程池中shutdown()和shutdownNow()方法的区别 一般情况下,当我们频繁的使用线程的时候,为了节约资源快速响应需求,我们都会考虑使用线程池,线程池使用完毕都会想着关闭,关闭的时候一般情况下会用到shutdown和shutdow…...

高可用/性能

文章目录1.数据库系统架构发展(1)单库架构(2)主备架构(3)主从架构2.主从复制主从同步配置主从复制模式(1)异步复制(2)半同步复制(3)全…...

PriorityQueues优先队列

优先队列优先队列(priority queue)是计算机科学中的一类抽象数据类型。优先队列中的每个元素都有各自的优先级,优先级最高的元素最先得到服务;优先级相同的元素按照其在优先队列中的顺序得到服务。优先队列通常使用“堆”&#xf…...

arm 堆栈

先转一篇 stm32 堆和栈(stm32 Heap & Stack)【worldsing笔记】_stm32堆栈_slj_win的博客-CSDN博客 关于堆和栈已经是程序员的一个月经话题,大部分有是基于os层来聊的。 那么,在赤裸裸的单片机下的堆和栈是什么样的分布呢?以下是网摘&…...

leetcode-面试题 05.02. Binary Number to String LCCI

Description Given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print the binary representation. If the number cannot be represented accurately in binary with at most 32 characters, print “ERROR”. Example1: Input: 0.625Outpu…...

C语言函数阐述

C 函数 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。 您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上&#xff0c…...

二叉树——把二叉搜索树转换为累加树

538. 把二叉搜索树转换为累加树 链接 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒一下&#xf…...

Java使用DFA算法实现敏感词过滤

1 前言敏感词过滤就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模块中你可以加入敏感词,然后根据加入的敏感词去过滤输入内容中的敏感词并进行…...

UG NX二次开发(C#)-外挂 - 配置文件说明(.men文件/.rtb文件/.trb文件)

文章目录 1、前言2、UG NX菜单说明2.1UG NX的Ribbon样式说明2.2 UG NX的Ribbon配置文件3、外挂的加载配置文件说明3.1 创建配置文件夹3.2 填写.men文件3.2 填写.rtb文件3.2 填写.tbr文件4、将外挂加载到UG NX菜单中5、重启UG NX,就可以实现外挂加载了。1、前言 UG NX二次开发…...

Web3中文|日本元宇宙经济“狂飙”

2月27日,三菱、富士通和其它科技公司发布关于建立“日本元宇宙经济区”的协议,表示将联手从角色扮演游戏的角度创建开放的元宇宙基础设施,以推动日本的Web3战略。据了解,日本一直在努力将Web3技术纳入其国家议程,去年1…...

@Autowired和@Resource到底有什么区别

Autowired 和 Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它。 Autowired 和 Resource 的…...

2023年最新阿里云服务器价格表出炉(精准收费标准及配置价格表)

阿里云在全球率先宣布了基于 Intel Ice Lake 处理器的第七代云服务器ECS,性能提升的同时降低了报价,性价比更高了。进入2023年阿里云服务器价格依然是大家关心的问题,事实上阿里云服务器租用价格和最新收费标准都可以通过官方云服务器计算器来…...

ElasticSearch - SpringBoot整合ES实现文档的增删改操作

文章目录1. ElasticSearch和kibana的安装和配置2. SpringBoot 项目环境搭建3. 创建索引4. 索引文档5. 更新文档6. 删除文档https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.htmlhttps://www.elastic.co/guide/cn/elasticsearch/guide/curre…...

嵌入式 LVGL移植到STM32F4

目录 LVGL简介 1、特点 2、LVGL的硬件要求 3、相关网站 4、LVGL源码下载 5、LVGL移植要求 5.1 移植过程-添加源码 2、更改接口文件 3、显示实现 4、添加外部中文字体的方法 5、编译下载后有几种情况 6、调用显示 6、GUI-Guider使用 6.1 安装软件 6.2 使用…...

VSCode——SSH免密登录

文章目录本地PC端(一般为Windows)1. 检查自己是否已经生成公钥2. 配置VScode的SSH config远程服务器端1. 服务器新建授权文件2. 赋权限3. 重启远程服务器的ssh服务最全步骤:【设置ssh免密不起作用?彻底搞懂密钥】vscode在remote S…...

python未来应用前景怎么样

Python近段时间一直涨势迅猛,在各大编程排行榜中崭露头角,得益于它多功能性和简单易上手的特性,让它可以在很多不同的工作中发挥重大作用。 正因如此,目前几乎所有大中型互联网企业都在使用 Python 完成各种各样的工作&#xff0…...

webpack基本使用和开发环境配置

目录 1 webpack 基本使用 01 webpack 简介 02 webpack 初体验 2 webpack开发环境配置 03 打包样式资源 04 打包html资源 05 打包图片资源 06 打包其他资源(以打包icon为例) 07 devServer 08.开发环境配置 1 webpack 基本使用 由于笔记文档没有…...

3.2 http协议

一.HTTP协议1.概述是计算机网络的核心概念,是一种网络协议网络协议种类非常多,其中IP,TCP,UDP...其中还有一个应用非常广泛的协议.HTTPHTTP协议是日常开发中用的最多的协议HTTP处在TCP/IP五层协议栈的应用层HTTP在传输层是基于TCP的,(http/1 HTTP/2是基于TCP,最新版本的HTTP/3是…...

页面访问升级出错怎么解决

相信大家在访问网站的时候时常会遇到页面访问界面升级,暂时不可能进行访问操作,可能遇到这种情况很多小伙伴们都不知道怎么版,其实互联网网页在正常使用过程中是不会出现这种问题的。那么如果遇到页面访问界面升级怎么办?页面访问界面升级通…...

leetcode 181. 超过经理收入的员工

SQL架构 表:Employee ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | | salary | int | | managerId | int | ---------------------- Id是该表的主键。 该表的…...

任务类风险漏洞挖掘思路

任务类风险定义: 大部分游戏都离不开任务,游戏往往也会借助任务,来引导玩家上手,了解游戏背景,增加游戏玩法,提升游戏趣味性。任务就像线索,将游戏的各个章节,各种玩法,…...

2023年Dubbo常见面试题

2023年Dubbo常见面试题 Dubbo 中 zookeeper 做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么? 可以通信的,启动 dubbo 时,消费者会从 zk 拉取注册的生产者的地址接口等数据,缓存在本地。…...

星光2开发板使用ECR6600U无线wifi网卡的方法

visionfive2 开发板性能还是不错的,有些人买的时候会带一个无线wifi网卡,但是官方提供的操作系统没有驱动。 所以需要自己编驱动(他大爷的)。 还好有人已经踩过坑了。 星光2之USB无线网卡使用教程【新增RTL8832AU WiFi6双频无线…...

【ArcGIS Pro二次开发】(11):面要素的一键拓扑

在工作中,经常需要对要素进行拓扑检查。 在ArcGIS Pro中正常的工作流程是在数据库中【新建要素数据集——新建拓扑——将要素加入拓扑——添加规则——验证】,工作流程不算短,操作起来比较繁琐。 下面以一个例子演示如何在ArcGIS Pro SDK二次…...

【实现点击下载按钮功能 Objective-C语言】

一、实现点击下载按钮功能, 1.接下来,我们再实现另外一个功能,是什么,点击下载按钮吧: 点击下载按钮,是不是要有效果啊, 就是给大家实现这个功能, 首先,我们要实现单击这个效果,是不是要给按钮注册单击事件吧, 请问,这个按钮在哪里啊,是在控制器里面吗,不是,…...

界面控件DevExpress WinForm——轻松构建类Visual Studio UI(三)

DevExpress WinForm拥有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任…...

做网站如何安全 博客/山西网络营销外包

一、什么是检查点 LoadRunner中检查点是用来判断脚本是否执行成功的。如果不加检查点,只要服务器返回的HTTP状态码是200,VuGen就认为脚本执行通过了。但是很多情况下服务器返回200并不代表脚本执行通过了,比如:登录操作&#xff0…...

茶网站源码/上海培训机构

from: http://www.jasongj.com/2015/01/02/Kafka%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/ 一种非常常用的选举leader的方式是“majority vote”(“少数服从多数”),但Kafka并未采用这种方式。这种模式下,如果我们有2f1个replica&am…...

代理加盟项目/seo为什么要进行外部优化

数据:是运送信息的实体。 信号:则是数据的电气的或电磁的模拟数据:运送信息的模拟信号。模拟信号:连续变化的信号。 数字信号:取值为有限的几个离数字数据:取值为不连续数值的数据。单工通信:即…...

高端网站建设推来客地址/优化公司怎么优化网站的

刚看到这个效果的时候还真是和ReactNative的效果一致,属性也基本的一样. view这个组件就是一个视图组件使用起来非常简单。 主要属性: flex-direction: 主要两个特性”row”横向排列”column”纵向排列 justify-content 主轴的对齐方式&a…...

附近网站建设公司/百度seo收费

我正在尝试使用TABLE_PER_CLASS策略创建继承,但我想为每个表创建不同的主键是否可能?我有一个类Register,它有数百万个实例,其中一些实例是“特殊的”,并且对于它们的列和额外的列有不同的规则.MappedSuperclasspublic abstract class Register {IdColumn(nullable …...

达州城乡建设网站/广告

1、问题:这两天写的APP需要在一个页面中使用echarts图表,发现一个问题:在进入改页面初始化时,图表会缩小。但是把容器宽高设置为px就可以了,但是写的移动端需要适配必须rem。 2、问题根因:div还没有创建出来…...