C++证道之路第十三章类继承

news/2024/5/14 16:53:12

一、一个简单的基类

从一个类派生出另一个类时,原始类称为基类,继承类称为派生类。

派生类对象储存了基类的数据成员(派生类继承了基类的实现)。

派生类对象可以使用基类的方法(派生类继承了基类的接口)。

需要在继承特性中添加什么呢?

派生类需要自己的构造函数。

派生类可以根据需要添加额外的数据成员和成员函数。

构造函数:访问权限的考虑

派生类不能直接访问基类的私有成员,而必须通过基类方法进行访问。具体的说,派生类构造函数必须使用基类构造函数。

有关派生类构造函数的要点如下:

首先创建基类对象;

派生类构造函数应通过成员初始化列表将基类信息传递给基类构造函数;

派生类构造函数应初始化派生类新增的数据成员;

注意:创建派生类对象时,程序首先调用基类构造函数,然后在调用派生类构造函数。基类构造函数负责初始化继承的数据成员;派生类构造函数主要用于初始化新增的数据成员。派生类的构造函数总是调用一个基类构造函数。可以使用初始化列表语法指明要使用的基类构造函数,否则将使用默认的基类构造函数。

派生类对象过期时,程序将首先调用派生类析构函数,然后在调用设计类析构函数。

派生类和基类之间的特殊关系

派生类与基类之间有一些特殊关系。

其中之一是派生类对象可以使用基类的方法,条件是方法不是私有的

另外两个重要的关系是:基类指针可以在不进行显式类型转换的情况下指向派生类对象;基类引用可以在不进行显式类型转换的情况下引用派生类对象;

继承is-a关系

派生类和基类之间的特殊关系是基于C++继承的底层模型的。实际上,C++有3中继承方式:公有继承、保护继承和私有继承。

公有继承是最常用的方式,它建立一种is-a的关系,即派生类对象也是一个基类对象,可以对基类对象执行的任何操作,也可以对派生类对象执行。

多态公有继承

在派生类中重新定义基类的方法;

使用虚方法。

注意:如果要再派生类中重新定义基类的方法,通常应将基类方法声明为虚的。这样,程序将根据对象类型而不是引用或指针的类型来选择方法版本。为基类声明一个虚析构函数 也是一种惯例。

静态联编和动态联编

程序调用函数时,将使用哪个可执行代码块呢?编译器负责回答这个问题。将源代码中的函数调用解释为执行特定的函数代码块被称为函数名联编。

提示:如果要在派生类中重新定义基类的方法,则将它设置为虚方法;否则设置为非虚方法。

使用虚函数时,在内存和执行速度方面有一定的成本,包括:

每个对象都将增大,增大量为储存地址的空间;

对于每个类,编译器都创建一个虚函数地址表(数组)。

对于每个函数调用,都需要执行一项额外的操作,即到表中查找地址。

虽然非虚函数的效率比虚函数稍高,但不具备动态联编功能。

有关虚函数注意事项

在基类方法的生命中使用关键字virtual可使该方法在基类以及所有的派生类(包括从派生类派生出来的类)中是虚的。

如果使用指向对象的引用或指针来调用虚方法,程序将使用为对象类型定义的方法,而不使用为引用或指针类型定义的方法。这成为动态联编或晚期来那边。这种行为非常重要,因为这样基类指针或引用可以指向派生类对象。

如果定义的类将被用作基类,则应将那些要在派生类中重新定义的类方法声明为虚的。

构造函数

构造函数不能是虚函数

析构函数

析构函数应当是虚函数,除非类不用做基类

给类定义一个虚析构函数并非错误,即使这个类不用做 基类;这只是一个效率方面的问题。

提示:通常应给基类提供一个虚析构函数,即使它并不需要析构函数。

友元

友元不能是虚函数,因为友元不是类成员,而只有成员才能时虚函数。如果由于这个原因引起了设计问题,可以通过让友元函数使用虚成员函数类解决。

没有重新定义

如果派生列没有重新定义函数,将使用该函数的基类版本。如果派生类位于派生链中,则将使用最新的虚函数版本,例外的情况是基类版本是隐藏的。

如果重新定义继承的方法,应确保与原来的原型完全相同,但如果返回类型是基类引用或指针,则可以修改为指向派生类的引用或指针。这种特性被称为返回类型协变,因为允许返回类型随类类型的变化而变化。

如果基类声明被重载了,则应在派生类中重新定义所有的基类版本。

访问控制:protected

派生类的成员可以直接访问基类的保护成员,但不能直接访问基类的私有成员。

警告:最好对类数据成员采用私有访问控制,不要使用保护访问控制;同时通过基类方法是派生类能够访问基类数据。

抽象基类

继承和动态内存分配

第一种情况:派生类不使用new

第二种情况:派生类使用new

有关使用基类方法的说明:

以公有方式派生的类的对象可以通过多种方式来使用基类的方法。

派生类对象自动使用继承而来的基类方法,如果派生类没有重新定义该方法。

派生列的构造函数自动调用基类的构造函数。

派生类的构造函数自动调用基类的默认构造函数,如果没有再成员初始化列表中指定其他构造函数。

派生类构造函数显式的调用成员初始化列表中指定的基类构造函数。

派生类方法可以使用作用域解析运算符来调用公有的和受保护的基类方法。

派生类的友元函数可以通过强制类型转换,将派生类引用或指针转换为基类引用或指针,然后使用该引用或指针来调用基类的友元函数。


http://www.mrgr.cn/p/63426100

相关文章

windows电脑改造为linux

有个大学用的旧笔记本电脑没啥用了,决定把它改成linux搭一个服务器; 一、linux安装盘制作 首先要有一个大于8G的U盘,然后去下载需要的linux系统镜像,我下的是ubuntu,这里自选版本 https://cn.ubuntu.com/download/d…

沉浸式翻译 chrome 插件 Immersive Translate - Translate Website PDF

免费翻译网站,翻译PDF和Epub电子书,双语翻译视频字幕 📣 网络上口碑爆炸的网站翻译扩展工具【沉浸式翻译】⭐⭐⭐⭐⭐ 💻 功能特点如下: 📰 网站翻译 🚀 提供双语网站翻译,智能识…

java案例-服务端与客户端(传输对象)

需求 代码 SysUser 用户类Operation 操作类Client 客户端Server 服务端ServerReaderThread 服务端线程类 SysUser 用户类 需要实现Serializable 方便序列化,传输对象 public class SysUser implements Serializable {private String username;private String passwo…

《面向云计算的零信任体系第1部分:总体架构》行业标准正式发布

中华人民共和国工业和信息化部公告2024年第4号文件正式发布行业标准:YD/T 4598.1-2024《面向云计算的零信任体系 第1部分:总体架构》(后简称“总体架构”),并于2024年7月1日正式施行。 该标准由中国信通院牵头&#xf…

蓝桥杯ctf2024 部分wp

数据分析 1. packet 密码破解 1. cc 逆向分析 1. 欢乐时光 XXTEA #include<stdio.h> #include<stdint.h> #define DELTA 0x9e3779b9 #define MX (((z>>5^y<<2)(y>>3^z<<4))^((sum^y)(key[(p&3)^e]^z))) void btea(unsigned int* v…

工业异常检测

工业异常检测在业界和学界都一直是热门&#xff0c;近期其更是迎来了全新突破&#xff1a;与大模型相结合&#xff01;让异常检测变得更快更准更简单&#xff01; 比如模型AnomalyGPT&#xff0c;它克服了以往的局限&#xff0c;能够让大模型充分理解工业场景图像&#xff0c;判…

常用算法代码模板 (3) :搜索与图论

AcWing算法基础课笔记与常用算法模板 (3) ——搜索与图论 常用算法代码模板 (1) &#xff1a;基础算法 常用算法代码模板 (2) &#xff1a;数据结构 常用算法代码模板 (3) &#xff1a;搜索与图论 常用算法代码模板 (4) &#xff1a;数学知识 文章目录 0 搜索技巧1 树与图的存…

OpenHarmony 项目实战:智能体重秤

一、简介 本 demo 基于 OpenHarmony3.1Beta 版本开发&#xff0c;该样例能够接入数字管家应用&#xff0c;通过数字管家应用监测体重秤上报数据&#xff0c;获得当前测量到的体重&#xff0c;身高&#xff0c;并在应用端形成一段时间内记录的体重值&#xff0c;以折线图的形式…

在 UOS 统信安装 dotnet sdk 失败 提示 failed the verification

在 UOS 统信安装 dotnet sdk 失败 提示 You cannot install /home/lindexi/packages-microsoft-prod.deb that failed the verification, please go to Security Center - Security Tools - Application Security to adjust这是群里的伙伴报告的问题,从错误提示看需要在安全工…

制作一个能构建 dotnet AOT 的 gitlab ruuner 的 Debian docker 镜像

我的需求是需要有一个能够构建出 dotnet 的 AOT 包的环境,要求这个环境能解决 glibc 兼容依赖的问题,能打出来 x64 和 arm64 的 AOT 的包,且能够运行 gitlab runner 对接自动构建需求 以下是我列举的需求支持制作能在 UOS 系统和麒麟系统上运行的包 支持制作出来的包是 AOT …

个人学习总结__打开摄像头、播放网络视频的以及ffmpeg推流

前言 最近入手了一款非常便宜的usb摄像头&#xff08;买回来感觉画质很低&#xff0c;没有描述的4k&#xff0c;不过也够用于学习了&#xff09;,想着利用它来开启流媒体相关技术的学习。第一步便是打开摄像头&#xff0c;从而才能够对它进行一系列后续操作&#xff0c;诸如实…

将要上市的自动驾驶新书《自动驾驶系统开发》中摘录片段

全书共分15章&#xff1a;第1章是自动驾驶系统的概述&#xff08;场景分类、开发路径和数据闭环等&#xff09;&#xff0c;第2章简介自动驾驶的基础理论&#xff0c;即计算机视觉和深度学习等&#xff0c;第3&#xff5e;4章是自动驾驶的软硬件平台分析&#xff0c;包括传感器…

【PyTorch与深度学习】2、PyTorch张量的运算API(上)

课程地址 最近做实验发现自己还是基础框架上掌握得不好&#xff0c;于是开始重学一遍PyTorch框架&#xff0c;这个是课程笔记&#xff0c;这个课还是讲的简略&#xff0c;我半小时的课听了一个半小时。 1. 张量 1.1 张量操作 &#xff08;1&#xff09;chunk&#xff1a;将一…

Web前端开发之CSS_2

关系选择器CSS盒子模型弹性盒子模型文档流浮动清除浮动定位 1. 关系选择器 1.1 后代选择器 E F{} 选择所有被 E 元素包含的 F 元素&#xff0c;中间用空格隔开 <ul> <li>后代列表1</li> <div> <ol> <li>后代列表2</li> </ol>…

Vue从入门到精通-01-Vue的介绍和vue-cli

MVVM模式 Model&#xff1a;负责数据存储 View&#xff1a;负责页面展示 View Model&#xff1a;负责业务逻辑处理&#xff08;比如Ajax请求等&#xff09;&#xff0c;对数据进行加工后交给视图展示 关于框架 为什么要学习流行框架 1、企业为了提高开发效率&#xff1a;…

linux的压缩与备份

一、打包 格式&#xff1a;tar -参数 <打包文件名> <打包的目标> 作用&#xff1a;将文件或者目录打包 重要参数&#xff1a;-f 使用归档文件&#xff0c;一定要加上这个参数 -c 新建打包文件 -x 解包文件 -t 可以不用解包就能查看包文件内容 -v 打包和解包时显…

读天才与算法:人脑与AI的数学思维笔记13_Coq证明助手

读天才与算法:人脑与AI的数学思维笔记13_Coq证明助手1. 计算机 1.1. 对于计算机来说,它就很擅长处理这种重复而机械且计算量庞大的任务 1.1.1. 在速度与准确性等方面,计算机是远超过手工计算的 1.2. 计算机只能执行指令,并无自主创造力 1.…

Android --- 常见UI组件

TextView 文本视图 设置字体大小&#xff1a;android:textSize"20sp" 用sp 设置颜色&#xff1a;android:textColor"#00ffff" 设置倍距(行距)&#xff1a;android:lineSpacingMultiplier"2" 设置具体行距&#xff1a;android:lineSpacingExtra&q…

学习STM32第二十天

低功耗编程 一、修改主频 STM32F4xx系列主频为168MHz&#xff0c;当板载8MHz晶振时&#xff0c;系统时钟HCLK满足公式 H C L K H S E P L L N P L L M P L L P HCLK \frac{HSE \times PLLN}{PLLM \times PLLP} HCLKPLLMPLLPHSEPLLN​&#xff0c;在文件stm32f4xx.h中可修…

Django初步了解

目录 一、什么是Django 二、Django的设计模式 三、涉及的英文缩写及其含义 四、安装&#xff08;官方教程&#xff09; 一、什么是Django Django是一个Python Web框架&#xff0c;可以快速开发网站&#xff0c;提供一站式的解决方案&#xff0c;包括缓存、数据库ORM、后台…