面向对象特性中 继承详解
目录
概念:
定义:
定义格式
继承关系和访问限定符
基类和派生类对象赋值转换:
继承中的作用域:
派生类的默认成员函数
继承与友元:
继承与静态成员:
复杂的菱形继承及菱形虚拟继承:
虚拟继承使用格式
虚拟继承的原理解释
继承和组合
概念:
继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生的新类称为 派生类。
继承是类设计层次的复用,之前接触的复用都是简单的函数复用。
定义:
定义格式
下图中:Person是父类,也称作基类。Student是子类,也称作派生类

继承关系和访问限定符
继承方式和基类的访问限定符共同决定了派生类成员的访问权限

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

可以看出派生类成员访问权限是取 基类成员访问权限和派生类继承方式中较小的那个权限
基类和派生类对象赋值转换:
- 派生类对象 可以赋值给 基类的对象/基类的指针/基类的引用,这种被称作切片或切割,派生类比基类多出的那部分将会被切除,和基类相同部分进行赋值
- 基类对象不能赋值的派生类
- 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI(Run-Time Type Information)的dynamic_cast 来进行识别后进行安全转换。

继承中的作用域:
- 在继承体系中 基类 和 派生类 都有 独立的作用域
- 子类和父类中有同名成员时,子类成员将屏蔽父类会同名成员的直接访问,这种情况叫隐藏(原理就是编译器先在子类中寻找,再去父类寻找,如果子类中找到了就自然不会再去父类寻找了,所以可以使用作用域限定符直接指定父类的类域 去访问父类的同名成员)
- 如果是成员函数的隐藏,只需要函数名相同就构成隐藏
派生类的默认成员函数
首先,派生类一般是基类的拓展,我们可以将派生类分为 基类和拓展部分,对于基类部分的操作基本是沿用它自己的,拓展部分则是我们类似一个新类去定义
- 派生类的构造函数会自动调用(由编译器操作)基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
- 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
- 派生类的operator=必须要调用基类的operator=完成基类的复制。
- 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
- 派生类对象初始化先调用基类构造再调派生类构造。
- 派生类对象析构清理先调用派生类析构再调基类的析构。

继承与友元:
友元关系不能被继承,也就是说基类友元不能访问子类私有和保护成员
继承与静态成员:
基类定义了static 静态成员,则同一个继承体系中只有一个此成员。也就是说一个 static 静态成员被同一个继承体系共用,不论有多少个子类。
复杂的菱形继承及菱形虚拟继承:
单继承:一个子类只有一个直接父类时称这个继承关系为单继承

多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承

菱形继承:菱形继承是多继承的一种特殊情况。

菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant的对象中Person成员会有两份。

虚拟继承可以解决菱形继承的二义性和数据冗余的问题,原理下面会详细说明。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要随便在其他地方去使用。
虚拟继承使用格式
在继承方式前加上 virtual 关键字即可
class A
{public:
int _a;
};// class B : public A
class B : virtual public A //这里继承方式前面加上
{
public:
int _b;
};
虚拟继承的原理解释
上面 Person关系菱形虚拟继承的原理图:

由图可以看出,两个派生类对于同一个基类的虚拟继承,是在两派生类当中存下一个基类的偏移量指针,这个指针指向一张表,表叫做虚基表,指针叫做虚基表指针。通过这个表与存下的指针,就能找到基类的位置,所以就不会出现二义性和数据冗余的问题了。
相当于将子类 虚拟继承的成员/函数 换成对应的地址,通过这个地址找到最初的父类,这样继承的就完全是同一个东西了,不会重复也不会出现歧义
继承和组合
- public继承是一种 is-a 的关系。也就是说每个派生类对象都是一个基类对象。
- 组合是一种 has-a 的关系。比如 B 组合了 A,则每个 B 对象中都有一个 A 对象
- 优先使用对象组合,而不是类继承
- 继承这种通过生成派生类的复用通常被称为白箱复用,因为在继承方式中,基类的内部细节对子类是可见的,这一定程度破坏了基类的封装,基类的改变可能对派生类有很大影响(派生类的有些功能实现可能就是用基类的细节来定义的)。这样派生类和基类间的依赖关系很强,耦合度高。
- 组合则相反,被称为黑箱复用,被组合的对象内部细节是不可见的,其必须具有良好定义的接口,我们只需要了解其功能和接口使用即可。这样的话就被封装得很好,组合类间没有很强的依赖关系,耦合度低。
- 实际尽量多用组合,组合耦合度低,代码维护性好。但还是要根据实际情况,若更适合继承(is-a 的关系),就用继承。
相关文章:
面向对象特性中 继承详解
目录 概念: 定义: 定义格式 继承关系和访问限定符 基类和派生类对象赋值转换: 继承中的作用域: 派生类的默认成员函数 继承与友元: 继承与静态成员: 复杂的菱形继承及菱形虚拟继承: 虚…...
C++ | Leetcode C++题解之第455题分发饼干
题目: 题解: class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int m g.size(), n s.size();int count 0;for (int i 0, j 0; i < …...
java版基于Spring Boot + Mybatis在线招投标|评标|竞标|单一采购|询价|邀标|在线开标|招标公告发布|评审专家|招投标采购系统源码
一、项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,…...
Anaconda的安装与环境设置
文章目录 一、Anaconda介绍二、Anaconda环境搭建1. 下载Anaconda(1)官网下载(2)清华大学镜像 2. 安装Anaconda3.配置环境变量4.检验conda是否安装成功5.更改镜像源6.若菜单栏没有conda prompt 三、虚拟环境1.创建、查看、删除虚拟环境2.激活、退出虚拟环境 四、CUDA、Pytorch、…...
使用FastAPI做人工智能后端服务器时,接口内的操作不是异步操作的解决方案
在做AI模型推理的接口时,这时候接口是非异步的,但是uvicorn运行FastAPI时就会出现阻塞所有请求。 这时候需要解决这个问题: api.py: import asyncio from fastapi import FastAPI from fastapi.responses import StreamingResp…...
Leetcode 3312. Sorted GCD Pair Queries
Leetcode 3312. Sorted GCD Pair Queries 1. 解题思路2. 代码实现 题目链接:3312. Sorted GCD Pair Queries 1. 解题思路 这一题的话坦率来说没有搞定,后来是找的大佬的代码抄了一下…… 整体来说这道题思路上还是比较暴力的,还是一个二重…...
用 Delphi 做了一个简单的 CMS
Delphi 代码上面花的时间最少。 前提是你要熟悉 Delphi 的 WebBroker 框架。不熟悉也没关系,5分钟就可以入门,10分钟就熟悉了。 CMS 就是个基于 WEB 的内容管理嘛。相当于一个简单的没有跟贴功能的 BBS。这样的东西,后边是数据库࿰…...
ASK, PSK, FSK, DPSK
ASK, PSK, FSK, DPSK详解: 这四种调制方式都是数字调制技术,用于将数字信号转换成适合在信道上传输的模拟信号。它们的主要区别在于如何用模拟信号的变化来表示数字信息。 1. ASK (Amplitude Shift Keying) 幅移键控: 原理: ASK 通过改变载波信号的幅…...
【Linux】认识Linux内核中进程级别的文件结构体【files_struct】&文件IO模型初步演示
前言 大家好吖,欢迎来到 YY 滴 系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《Linux》…...
[Offsec Lab] ICMP Monitorr-RCE+hping3权限提升
信息收集 IP AddressOpening Ports192.168.52.218TCP:22,80 $ nmap -p- 192.168.52.218 --min-rate 1000 -sC -sV -Pn PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9p1 Debian 10deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 de:b5:23:89:bb:9f:d4:1…...
Studying-多线程学习Part4 - 异步并发——async future、packaged_task、promise
异步并发——async future packaged_task promise 1.async、future 是C11引入的一个函数模版,用于异步执行一个函数,并返回一个future对象,表示异步操作的结果。使用 async 可以方便地进行异步编程,避免了手动创建线程和管理线程…...
【Java基础】用Scanner类获取控制台输入
目录 Scanner类是什么导入并创建读取一个数读取字符串读取一行读取直到空白字符为止读取多个数直到^z读取一个字符 Scanner类是什么 在Java中,Scanner 是一个非常有用的类,用于从各种输入源(如键盘、文件或其他输入流)读取数据。…...
微服务seata解析部署使用全流程
官网地址: Seata 是什么? | Apache Seata 1、Seata术语 用来管理分布式事务,由阿里巴巴出品。 【1、TC (Transaction Coordinator) - 事务协调者】 用来维护事务的,包括主事务和分支事务。 【2、TM (Transaction Manager) - …...
Linux性能调优技巧
目录 前言1. CPU性能优化1.1 调整CPU调度策略1.2 合理分配多核处理 2. 内存性能优化2.1 调整内存分配策略2.2 缓存和分页优化 3. 磁盘I/O性能优化3.1 使用合适的I/O调度器3.2 磁盘分区和文件系统优化 4. 网络性能优化4.1 优化网络参数4.2 调整网络拥塞控制算法 5. 系统监控与优…...
python 实现sha1算法
sha1算法介绍 SHA-1(Secure Hash Algorithm 1,安全散列算法1)是一种密码散列函数,由美国国家安全局(NSA)设计,并由美国国家标准技术研究所(NIST)发布为联邦数据处理标准…...
ejb-ref元素
ejb-ref 是用于在 Java EE (现在称为 Jakarta EE) 中引用 Enterprise JavaBeans (EJB) 的一个元素,主要用于定义和配置 SLEE (Service Logic Execution Environment) 组件中的 EJB 依赖关系。通过这个引用,SBB (Service Building Block) 可以轻松地访问和…...
Perl 子程序(函数)
Perl 子程序(函数) Perl 是一种高级、解释型、动态编程语言,广泛用于CGI脚本、系统管理、网络编程、 finance, bioinformatics, 以及其他领域。在Perl中,子程序(也称为函数)是组织代码和重用代码块的重要方…...
ElasticSearch 备考 -- Snapshot Restore
一、题目 备份集群下的索引 task,存储快照名称为 snapshot_1 二、思考 这个涉及的是集群的备份,主要是通过创建快照,涉及到以下2步骤 Setp1:注册一个备份 snapshot repository Setp2:创建 snapshot 可以通过两种方…...
【Linux】进程替换、命令行参数及环境变量(超详解)
目录 进程替换 替换函数的含义 命令行参数 环境变量 PATH 进程替换 我们先看代码: 1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5 printf("process...begin!\n");6 7 execl("/usr/bin/ls","ls"…...
MySQL事务日志—redo日志介绍
MySQL事务日志—redo日志 事务有4种特性: 原子性、一致性、隔离性和持久性。 那么事务的四种特性到底是基于什么机制实现? 事务的原子性、一致性由事务的 undo 日志事务的隔离性由锁机制和MVCC实现。事务的持久性由redo 日志来保证。 两类日志概述:…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
