Cxx primer-chap15-Object-Oriented Programming
- 面向对象编程的三个基本概念:数据抽象、继承和动态绑定(多态):

- 基类应该提供一些类型无关的成员函数定义,将与类相关的函数留给不同的派生类定义:
,派生类是通过类派生列表(class derivation list)对基类进行声明:
- 对于那些与类相关的成员函数,我们需要在基类中声明为
virtual,在派生类用用关键字override显式强调我们要重新定义的成员函数:
- 动态绑定(
dynamic binding,也叫run-time binding)可以用一份代码在多个对象上执行:
- 对于涉及继承的几个类而言,基类的几个特征是:1. 对于类相关的成员函数定义成(纯)虚函数。2. 对于让派生类访问,但用户无法访问的成员,用
protected关键字。3. 基类的析构函数必须为虚函数。
- 除了
static member和constructor,我们都可以声明为virtual:
- 基类中对成员的访问控制,影响派生类对成员的访问:
,简单讲,我们可以将派生类当做基类的特殊用户来看待。目前将,有三个用户:类的实现者、类的用户和派生类。 - 对于派生类而言,需要在(
class derivation list,类派生列表)指定其基类和打算override来自基类的成员:
。对于派生列表中用public继承的基类,我们可以正常使用动态绑定,此外可以将基类的接口作为派生类接口的一部分:
- 派生类对象由多个部分组成,正因如此,才允许动态绑定。以及
Derived-to-Base(指针)的转换,注意转换的部分是we can bind a base-class reference or pointer to the base-class part of a derived object.:
,即
- 不管是什么类,每个类都负责自己成员的初始化:
,关于在继承的情况下,构造函数的执行顺序是从基类到派生类:
- 派生类可以直接访问基类中
protected和public限定的成员,但是要尊重类的接口。此外值得注意的是:派生类的作用域被嵌入在基类作用域的里面:
- 对于
static成员,它们不属于对象,所以它们自始至终只有一份代码:
- 通过
final关键字防止该类被继承:
- 派生类(指针)到基类(指针)的转换是理解C++中OOP的重中之重:

- 在继承场景下,基类的指针和引用的静态类型和动态类型可能会不同:
,对于变量或表达式的静态类型在编译时确定,而动态类型是其在内存中表示的类型,在运行时确定。 - 因为派生类到基类的转换是因为基类的指针/引用可以绑定到派生类的基类部分。但是基类作为一个独立的对象时,它可能不存在派生类的成员,所以不存在基类到派生类的隐式转换:

- 派生类到基类的隐式转换的前提是用基类的指针/引用,派生类与基类的对象之间是无法转换的:
,强制将派生类转换成基类时就会发生sliced down:
- 继承层次下的
virtualfunction必须要定义,因为其是否使用只能在运行时确定:
dynamic bindinghappens only when a virtual function is called through a pointer or a reference of base class:
,对于其他对象类型在编译时确定的情况下,调用的成员函数就是确定的:
,dynamic binding引出C++的polymorphism:
- 如果一个成员函数在base class是virtual,那么它在后续的派生类中也是隐式的virtual,此外派生类override基类的虚函数时,需要保证参数列表一致:

- 在派生类中,覆盖相应的虚函数时,可以使用
override关键字通知编译器来检查派生类中重定义时是否与基类中的参数列表相同:
,也可以声明成员函数为final来防止该函数被override。 - 我们也可以使用作用域操作符来规避动态绑定机制:

- 纯虚函数通常是一个通用的概念,负责规定函数签名,实现细节由具体的派生类决定:
,如果非要定义纯虚函数,我们只能在类外进行。 - 抽象基类不能定义对象,不过应该可以定义指针/引用:

- 每个类都负责自身成员的初始化,这里要注意在继承框架下,构造函数的调用顺序:

- 每个类也控制它的成员是否允许被“用户(类的使用者/派生类)”访问:

- 从派生类访问基类基础来的成员受两个方面影响:该成员在基类内的访问声明符,在派生类的派生列表中的访问声明符:

- 派生类到基类的隐式转换需要条件:

- 类的三个使用者:类的实现者、类的用户和派生类:

friendship不可被传递和继承:
- 关键字
struct和class的默认访问声明符和默认派生访问声明符不同:
- 派生类的作用域是嵌入到基类里面:

- 编译时的静态类型确定某个成员函数是否可以被调用,因为命名查询是从静态类型所在的类开始,然后向基类搜索的:

- 如果派生类具有与基类的同名成员名称,因为派生类的作用域是嵌入在基类的作用域的,所以此时派生类的该成员会隐藏基类同名成员:
,我们也可以使用作用域操作符来显式地调用基类中隐藏的成员:
- 在继承场景下,函数调用的解析过程,注意在类型检查前做命名查询:

- 在继承的场景下, 为了能够让基类的指针释放动态绑定的派生类对象,通过将基类的析构函数声明为
virtual:
,否则就会发生undefined behavior:
- 如果一个类显式定义了一个析构函数,那么编译器不会默认合成
move operation:
- 派生类的析构函数会自动调用基类的析构:

- 在继承场景下,析构函数的执行顺序与构造函数相反:
,因为在执行基类的构造/析构时,如果是派生类的对象,那么该对象此时就是不完整的。为了安全考虑,在构造/析构执行虚函数时就不谈动态绑定一说:
- 容器存储继承层次中的对象时应该间接进行:
,例如使用指向基类的指针等。
相关文章:
Cxx primer-chap15-Object-Oriented Programming
面向对象编程的三个基本概念:数据抽象、继承和动态绑定(多态):基类应该提供一些类型无关的成员函数定义,将与类相关的函数留给不同的派生类定义:,派生类是通过类派生列表(class derivation list…...
当黑神话遇上AI:悟空背后的策划逆袭战
声明:此篇为 ai123.cn 原创文章,转载请标明出处链接:https://ai123.cn/2192.html 哈喽,亲爱的游戏迷,随着《黑神话:悟空》的上线,大家都在忙着“直面天命”了吧?今天我想和大家分享最…...
外呼触发通知发送闪信(mod_cti基于FreeSWITCH)
文章目录 前言联系我们手动外呼配置方法例子一:接收到180或183时触发闪信发送例子二:挂断后触发闪信发送 自动外呼配置方法例子:接收到180或183时触发闪信发送 前言 在呼叫中心中间件中,自动外呼触发闪信发送,我们可以…...
8.Java基础概念-方法
欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 Facts speak louder than words! 什么是方法 方法是程序…...
360安全浏览器如何彻底卸载
360安全浏览器是一款广泛使用的网络浏览工具,然而由于各种原因,用户可能需要将其从计算机中彻底移除。下面小编就给大家分享几种彻底卸载360安全浏览器的方法,避免留下影响系统性能的残留信息。(本文由https://chrome.cmrrs.com/站…...
构建基于LLM的应用程序——使用LLM的搜索和推荐引擎
在上一章中,我们介绍了构建对话应用程序的核心步骤。我们从一个基础的聊天机器人开始,然后逐步添加了更复杂的组件,例如记忆、非参数化知识和外部工具。借助LangChain的预构建组件以及Streamlit的UI渲染,这一切都变得相对简单。尽…...
Unity3D 模型碰撞检测问题详解
前言 在Unity3D游戏开发中,模型碰撞检测是至关重要的一环,它负责处理物体之间的交互、触发事件以及物理效果的实现。通过精确的碰撞检测,游戏世界得以呈现出更为真实和动态的交互体验。本文将详细介绍Unity3D中的碰撞检测原理、技术实现以及…...
springcloud集成seata实现分布式事务
Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 官网:Apache Seata 文章目录 一、部署1.下载2.修改配置,nacos作注册中心,db存储 二、集成到springcloud项目1.引入依赖2.修改…...
[Leetcode 61][Medium]-旋转链表
目录 一、题目描述 二、整体思路 三、代码 一、题目描述 原题链接 二、整体思路 首先发现这样的规律:当k大于等于链表中节点总数n时,会发现此时旋转后的链表和kk%n时的旋转后的链表一样。同时对于特殊情况n0和n1时,无论k的值为多少都可以…...
高效分页策略:掌握 LIMIT 语句的正确使用方法与最佳实践
本文主要介绍limit 分页的弊端及线上应该怎么用 LIMIT M,N 平时经常见到使用 <limit m,n> 合适的 order by 来实现分页查询,这样做到底性能如何呢? 先来简单分析下,然后再实际验证一下。 无索引条件下,需要做大量的文件排…...
拼图游戏02
文章目录 概要整体架构流程代码过程小结 概要 现在需要将图片添加界面中 关键点在于它如何动态地根据游戏状态更新用户界面。它使用了Swing的布局管理器来定位组件,并且通过ImageIcon和JLabel来显示图像。注意,路径字符串中的反斜杠在Java中是转义字符…...
在本地进行Django支付宝扫码支付-当面付开发
这几天涉及到一个个人项目的支付开发场景,正好完成之后,做一下开发记录,给有需要的朋友做一下参考 涉及安装Python环境请参考我专栏中的历史文章,这里不再重复说明 环境: Python3.11 使用Django框架 因本次代码为沙…...
redis-RedisTemplate.opsForGeo 的geo地理位置相关的方法演示
主要方法:add : 添加一个地理位置distance: 计算两个元素之间的距离hash: 获取元素经纬度坐标经过geohash算法生成的base32编码值position: 获取集合中任意元素的经纬度坐标,可以一次获取多个radius:查询某个坐标或某个成员&#…...
做短视频矩阵要十几人团队吗?云微客助阵,一人即可
现在市面上主流的新媒体平台都进军了短视频赛道,对于众多企业和个人来说,短视频矩阵更是成为了提升影响力和拓展业务的关键。企业或个人可以根据自身产品特点和目标用户群体,构建账号矩阵,在多平台上建立账号矩阵,还可…...
常用语音识别开源工具的对比与实践
常用语音识别开源工具的对比 一.工具概述 1. WeNet 设计目标:WeNet 的设计主要聚焦于端到端(E2E)语音识别,特别是在流式识别方面的优化。其目标是提供一个可以在实际应用中达到低延迟和高精度的系统。模型架构: Con…...
Fortify代码安全测试工具在静态应用安全测试(SAST)方面针对典型问题的改进
Fortify代码安全测试工具作为行业内资深的老牌软件安全测试工具,可以同时支持静态代码扫描和动态代码扫描,本文我们讲述的主要是在静态代码扫描领域Fortify所面临的问题,以及最新的改进。 在应用安全领域,特别是静态应用安全测试&…...
AWS 消息队列服务 SQS
AWS 消息队列服务 SQS 引言什么是 SQSSQS 访问策略 Access Policy示例:如何为 DataLake Subscription 配置 SQS 引言 应用系统需要处理海量数据,数据发送方和数据消费方是通过什么方式来无缝集成消费数据的,AWS 提供 SQS 消息队列服务来解决…...
【iOS】——响应者链和事件传递链
事件传递 事件传递流程 发生触摸事件后,系统会将该事件封装成UIEvent对象加入到一个由UIApplication管理的事件队列 UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口…...
mysql查询慢
可能是连接数,或者缓存不够,可尝试添加如下参数,重启mysql [mysqld] max_connections50000 interactive_timeout604800 lock_wait_timeout600 wait_timeout604800 net_read_timeout604800 log-error/var/lib/mysql/mysqld.log slow_qu…...
【Java-==与equals】
与equals区别: 1.是关系运算符,equals()是0bject类中定义的方法 2.基本数据类型: 使用比较值,无法使用equals() 3.引用数据类型: 使用比较内存地址; 如果没有重写equals(),仍然调用的是0bject父类的equals(()方法,则比较的是内…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
