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

c++从入门到精通(五)--异常处理,命名空间,多继承与虚继承

异常处理

栈展开过程: 栈展开过程沿着嵌套函数的调用链不断查找,直到找到了与异常匹配的catch子句为止;也可能一直没找到匹配的catch,则退出主函数后查找过程终止。栈展开过程中的对象被自动销毁。

在栈展开的过程中,会自动运行类类型的局部对象的析构函数,这些异构函数不应该抛出异常。一旦在栈展开的过程中析构函数抛出了异常,且析构函数自身没能捕获到该异常,则程序将被终止。

抛出指针异常,要求在任何对应的处理代码存在的地方,指针所指的对象都必须存在。

捕获异常:

  • 声明的类型决定了处理代码所能捕获的异常类型。这个类型必须是完全类型,它可以是左值引用,但不能是右值引用。

  • 最后一点需要注意的是,异常声明的静态类型将决定catch语句所能执行的操作。如果catch的参数是基类类型,则catch无法使用派生类特有的任何成员。

  • 通常情况下,如果catch接受的异常与某个继承体系有关,则最好将该catch的参数定义成引用类型。

  • 因为catch语句是按照其出现的顺序逐一进行匹配的,所以当程序使用具有继承关系的多个异常时必须对catch语句的顺序进行组织和管理,使得派生类异常的处理代码出现在基类异常的处理代码之前。

  • 与实参和形参的匹配规则相比,异常和catch异常声明的匹配规则受到更多限制。此时,绝大多数类型转换都不被允许,除了一些极细小的差别之外,要求异常的类型和catch声明的类型是精确匹配的:

    【非常量向常量的转换,派生类向基类的转换,数组被转换为指针,函数被转换为指向该函数的指针】

    除此之外,包括标准算术类型转换和类类型转换在内,其他所有转换规则都不能在匹配catch的过程中使用。

重新抛出

一条catch语句通过重新抛出(rethrowing)的操作将异常传递给另外一个catch语句。这里的重新抛出仍然是一条throw语句,只不过不包含任何表达式:throw。一个重新抛出语句并不指定新的表达式,而是将当前的异常对象沿着调用链向上传递。

如果catch语句改变了参数内容,重新抛出异常后,只有当catch异常声明是引用类型时,我们对参数的修改才会被保留并继续传播。

捕获所有异常

我们使用省略号作为异常声明catch(...),通常于重新抛出语句一起使用,其中catch执行当前局部能能完成的工作,随后重新抛出异常。

如果catch(…)与其他几个catch语句一起出现,则catch(…)必须在最后的位置。出现在捕获所有异常语句后面的catch语句将永远不会被匹配。

函数try语句块于构造函数:

要想处理构造函数初始值抛出的异常,我们必须将构造函数写成函数try语句块。语句块。与这个try关联的catch既能处理构造函数体抛出的异常,也能处理成员初始化列表抛出的异常。

还有一种情况值得读者注意,在初始化构造函数的参数时也可能发生异常,这样的异常不属于函数try语句块的一部分。函数try语句块只能处理构造函数开始执行后发生的异常。和其他函数调用一样,如果在参数初始化的过程中发生了异常,则该异常属于调用表达式的一部分,并将在调用者所在的上下文中处理。

template <typenameT>
Blob<T>::Blob(std::initializer_list<T> il) try:data(std::make_shared<std::vector<T>>(il)){}catch(const std::bat_alloc &e){handle_out_of_memory(e);}

noexpect说明符:

对于一个函数来说,noexcept说明要么出现在该函数的所有声明语句和定义语句中,要么一次也不出现。该说明应该在函数的尾置返回类型之前。==我们也可以在函数指针的声明和定义中指定noexcept。在typedef或类型别名中则不能出现noexcept。==在成员函数中,noexcept说明符需要跟在const及引用限定符之后,而在final、override或虚函数的=0之前。

一旦一个noexcept函数抛出了异常,程序就会调用terminate以确保遵守不在运行时抛出异常的承诺

noexcept表达式:

返回一个bool类型的右值常量表达式,用于表示给定的表达式是否会抛出异常,和sizeof类似,noexcept不会求其运算对象的值。noexcept(recoup(i))如果recoup不抛出异常则为true。

在这里插入图片描述

指针,函数,拷贝控制与异常说明

如果我们为某个指针做了不抛出异常的声明,则该指针将只能指向不抛出异常的函数。

如果一个虚函数承诺了它不会抛出异常,则后续派生出来的虚函数也必须做出同样的承诺

当编译器合成拷贝控制成员时,同时也生成一个异常说明。如果对所有成员和基类的所有操作都承诺了不会抛出异常,则合成的成员是noexcept的。

异常类的层次:

在这里插入图片描述

命名空间

​ 一个命名空间的定义包含两部分:首先是关键字namespace,随后是命名空间的名字。在命名空间名字后面是一系列由花括号括起来的声明和定义。只要能出现在全局作用域中的声明就能置于命名空间内,主要包括:类、变量(及其初始化操作)、函数(及其定义)、模板和其他命名空间命名空间作用域后面无须分号。类的作用域后面又分号

​ 命名空间的定义可以是不连续的,我们可以新定义一个命名空间,也可以为已存在的命名空间添加一些新成员。因此我们可以把类的声明写在头文件中的命名空间中,把类的定义写在源文件的命名空间中。

​ 我们可以为一个项目定义一个命名空间,在该命名空间中定义不同的类,每个类都单独的头文件和定义源文件。使用的时候需要包含指定的头文件,并且应用该项目的命名空间。

模板特例化必须定义在原始模板所属的命名空间中。我们必须将模板特例化声明为std的成员(特例化std命名空间内的模板)

全局命名空间:

::name表示全局命名空间中的名字。

内联命名空间

​ 内联命名空间中的名字可以直接被外层命名空间访问。inline namesapce FifthEd{}关键字inline必须出现在命名空间第一次定义的地方,后续再打开命名空间的时候可以写inline,也可以不写。内联命名空间可以作为版本控制。

在这里插入图片描述

未命名的命名空间

​ 未命名命名空间在关键字namespace后直接跟花括号。未命名的命名空间中定义的变量拥有静态生命周期:它们在第一次使用前创建,并且直到程序结束才销毁。

​ 如果一个头文件定义了未命名的命名空间,则该命名空间中定义的名字将在每个包含了该头文件的文件中对应不同实体。

​ 和其他命名空间不同,未命名的命名空间仅在特定的文件内部有效,其作用范围不会横跨多个不同的文件。

​ 未命名的命名空间中定义的名字的作用域与该命名空间所在的作用域相同。如果未命名的命名空间定义在文件的最外层作用域中,则该命名空间中的名字一定要与全局作用域中的名字有所区别。

​ 未命名的命名空间可以嵌套使用,我们可以用外围命名空间的名字访问未命名的命名空间中的名字

定义名字别名

namespace asodfjdlkasjflksadjflk primer使用primer作为别名

namespace Qlib=asdlkfjlkasdjflk::asdfasd

using声明和using指示

​ using声明using std::vector。using声明会扩展候选函数集的规模。using声明的函数如果和当前作用域中的函数完全一致则using声明报错

​ using指示using namespace std. 如果存在多个using指示。则来自每个命名空间的名字都会成为候选函数集的一部分。using指示可以引入和当前作用域中完全重名的函数,我们只需要用作用域运算符就可以访问命名空间中的函数

​ using声明和using指示在作用域上的区别直接决定了它们工作方式的不同。对于using声明来说,我们只是简单地令名字在局部作用域内有效。相反,using指示是令整个命名空间的所有内容变得有效。它具有将命名空间成员提升到包含命名空间本身和using指示的最近作用域的能力。

在这里插入图片描述

​ 尽量避免使用using指示,在命名空间的定义源文件中可以使用using指示来简化编码。

函数实参传递和命名空间:

​ 当我们给函数传递一个类类型的对象时,除了在常规的作用域查找外还会查找实参类所属的命名空间。这一例外对于传递类的引用或指针的调用同样有效。查找规则的这个例外允许概念上作为类接口一部分的非成员函数无须单独的using声明就能被程序使用。

​ 对于标准库中的move和forward函数,他们几乎可以接收任何一个形参,因此我们编写的move和forward函数几乎一定会和标准库的相关函数冲突。因此我们通常书写std::move(std::forward)。

友元与命名空间

一个未声明的类或函数如果第一次出现在友元声明中,则我们认为它是最近的外层命名空间的成员。f2和f被隐式声明为A的成员。

在这里插入图片描述

​ 上述代码中,我们声明了一个C类的一个实例,调用f的时候会在C类所在的命名空间中查找(因为f接收一个类类型的实参),此时会找到f的隐士声明(在C类之前)。调用f2它不接受类类型参数,也因此不会查找C类所在的命名空间,也就找不到f2的声明语句。

多继承与虚继承

**继承的构造函数与多继承:**如果一个类从他的多个基类中继承了相同的构造函数,则这个类必须为该构造函数定义它自己的版本。下面代码中Base1和Base2都有一个接受const string &s的构造函数。

在这里插入图片描述

拷贝控制:多重继承的派生类如果定义了自己的拷贝/赋值构造函数和赋值运算符,则必须在完整的对象上执行拷贝、移动或赋值操作。只有当派生类使用的是合成版本的拷贝、移动或赋值成员时,才会自动对其基类部分执行这些操作。

**派生类向基类的转换:**在多继承关系中,编译器认为派生类向任何一个基类的转换都是一样好。因此函数调用过程中可能存在二义性错误。

对象、指针和引用的静态类型决定了我们能使用那些成员。

**多继承下的类作用域:**在多重继承的情况下,相同的查找过程在所有直接基类中同时进行。如果名字在多个基类中都被找到,则对该名字的使用将具有二义性。 对于一个派生类来说,从它的几个基类中分别继承名字相同的成员是完全合法的,只不过在使用这个名字时必须明确指出它的版本。

**虚继承:**避免在继承体系中,派生类里有多个基类(可以是顶层基类,也可以是中间基类)对象。

在默认情况下,派生类中含有继承链上每个类对应的子部分。如果某个类在派生过程中出现了多次,则派生类中将包含该类的多个子对象。

虚继承令某个类做出声明,承诺愿意共享它的基类。其中共享的基类对象称为虚基类。在这种机制下,无论虚基类在继承体系中出现了多少次,在派生类中都包含唯一一个共享的虚基类子对象。

在实际的编程过程中,位于中间层次的基类将其继承声明为虚继承一般不会带来什么问题。

无论基类是不是虚基类,派生类对象都能被可访问基类的指针或引用操作。

class Raccoon : public virtual ZooAnimal { }

**构造函数与虚继承:**派生类先

​ 含有虚基类的对象的构造顺序与一般的顺序稍有区别:首先使用提供给最低层派生类的构造函数的初始值初始化该对象的虚基类子部分,接下来按照直接基类在派生列表中出现的次序依次对其进行初始化。

如果派生类没有显示初始化虚基类,则虚基类的默认构造函数将被调用,如果虚基类没有默认构造函数,则代码将会发生错误。

编译器按照直接基类的声明顺序对其依次进行检查,以确定其中是否含有虚基类。如果有,则先构造虚基类,然后按照声明的顺序逐一构造其他非虚基类。

相关文章:

c++从入门到精通(五)--异常处理,命名空间,多继承与虚继承

异常处理 栈展开过程&#xff1a; 栈展开过程沿着嵌套函数的调用链不断查找&#xff0c;直到找到了与异常匹配的catch子句为止&#xff1b;也可能一直没找到匹配的catch&#xff0c;则退出主函数后查找过程终止。栈展开过程中的对象被自动销毁。 在栈展开的过程中&#xff0c…...

mock 数据( json-server )

json-server 实现数据 mock 实现步骤&#xff1a; 1. 在项目中安装 json-server npm install -D json-server 2. 准备一个 json 文件 server/data.json {"posts": [{ "id": "1", "title": "a title", "views"…...

Java多线程编程中的常见问题与陷阱汇总

线程安全问题 多线程环境下&#xff0c;多个线程同时访问共享资源时&#xff0c;可能会导致数据不一致或程序行为异常。常见的线程安全问题包括竞态条件、死锁、活锁等。 public class Counter {private int count 0;public void increment() {count;}public int getCount()…...

ARP Detection MAC-Address Static

一、ARP Detection&#xff08;ARP检测&#xff09; ✅ 定义&#xff1a; ARP检测是一种防止ARP欺骗攻击的安全机制。它通过监控或验证网络中的ARP报文&#xff0c;来判断是否存在伪造的ARP信息。 &#x1f50d; 工作原理&#xff1a; 网络设备&#xff08;如交换机&#xf…...

gcc/g++常用参数

1.介绍 gcc用于编译c语言&#xff0c;g用于编译c 源代码生成可执行文件过程&#xff0c;预处理-编译-汇编-链接。https://zhuanlan.zhihu.com/p/476697014 2.常用参数说明 2.1编译过程控制 参数作用-oOutput&#xff0c;指定输出名字-cCompile&#xff0c;编译源文件生成对…...

nginx配置之负载均衡

版权声明&#xff1a;原创作品&#xff0c;请勿转载&#xff01; 1.实验环境准备 准备3台linux服务器&#xff08;ubuntu和centos均可&#xff0c;本文使用centos7.9&#xff09;&#xff0c;两台web和一台负载均衡服务器&#xff0c;均安装nginx服务 主机名IP软件lb0110.0.0…...

相机Camera日志分析之十一:高通相机Camx hal预览1帧logcat日志process_capture_result详解

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:高通相机Camx 日志分析之五:camx hal预览1帧logcat日志process_capture_request详解 这一篇我们开始讲: 高通相机Camx 日志分析之十一:camx hal预览1帧logcat日志process_capture_result详解,这里我…...

Python函数库调用实战:以数据分析为例

一、引言 Python之所以在编程领域广受欢迎&#xff0c;很大程度上得益于其丰富且强大的函数库。这些函数库涵盖了从数据分析、科学计算到Web开发、机器学习等众多领域&#xff0c;极大地提高了开发效率。本文将以数据分析为例&#xff0c;介绍如何调用Python的一些常用函数库。…...

去年开发一款鸿蒙Next Os的window工具箱

持拖载多个鸿蒙应用 批量签名安装 运行 http://dl.lozn.top/lozn/HarmonySignAndFileManagerTool_2024-11-26.zip 同类型安卓工具箱以及其他软件下载地址汇总 http://dl.lozn.top/lozn/ 怎么个玩法呢&#xff0c;比如要启动某app, 拖载识别到包名 点启动他能主动读取包名 然后…...

顶层设计-IM系统架构

一、系统总体架构概览 即时通讯&#xff08;IM&#xff09;系统的核心目标&#xff0c;是让用户可以随时随地稳定地发送和接收消息。为了支撑成千上万用户同时在线交流&#xff0c;我们需要将整个系统划分成多个专职模块&#xff0c;每个模块只负责一件事情&#xff0c;彼此协同…...

信任的进阶:LEI与vLEI协同推进跨境支付体系变革

在全球经济版图加速重构的背景下&#xff0c;跨境支付体系正经历着前所未有的变革。2022年全球跨境支付规模突破150万亿美元&#xff0c;但平均交易成本仍高达6.04%&#xff0c;支付延迟超过2.7天。 这种低效率背后&#xff0c;隐藏着复杂的身份识别困境&#xff1a;超过40%的…...

安全性(三):信息安全的五要素及其含义

五要素及其含义 序号要素英文缩写含义说明1保密性Confidentiality仅授权用户才能访问信息&#xff0c;防止信息被非法获取或泄露&#xff08;例如&#xff1a;加密、访问控制&#xff09;2完整性Integrity信息在传输、存储和处理过程中保持准确、完整、未被篡改&#xff08;例…...

PHP 与 面向对象编程(OOP)

PHP 是一种支持面向对象编程&#xff08;OOP&#xff09;的多范式语言&#xff0c;但其面向对象特性是逐步演进而非原生设计。以下是关键分析&#xff1a; 1. PHP 对面向对象编程的支持 核心 OOP 特性&#xff1a; 类和对象&#xff1a; PHP 支持通过 class 关键字定义类&…...

Axios全解析:从基础到高级实战技巧

目录 核心特性 安装配置 基础使用 高级功能 错误处理 拦截器机制 请求取消 TypeScript支持 最佳实践 常见问题 1. 核心特性 1.1 核心优势 全平台支持&#xff1a;浏览器 & Node.js 双环境 自动转换&#xff1a;JSON数据自动序列化 拦截器系统&#xff1a;请求…...

EXO 可以将 Mac M4 和 Mac Air 连接起来,并通过 Ollama 运行 DeepSeek 模型

EXO 可以将 Mac M4 和 Mac Air 连接起来&#xff0c;并通过 Ollama 运行 DeepSeek 模型。以下是具体实现方法&#xff1a; 1. EXO 的分布式计算能力 EXO 是一个支持 分布式 AI 计算 的开源框架&#xff0c;能够将多台 Mac 设备&#xff08;如 M4 和 Mac Air&#xff09;组合成…...

数据库故障排查指南

数据库连接问题 检查数据库服务是否正常运行&#xff0c;确认网络连接是否畅通&#xff0c;验证数据库配置文件的正确性&#xff0c;确保用户名和密码无误。 性能问题 分析慢查询日志&#xff0c;优化SQL语句&#xff0c;检查索引使用情况&#xff0c;调整数据库参数配置&am…...

RBTree的模拟实现

1&#xff1a;红黑树的概念 红⿊树是⼀棵⼆叉搜索树&#xff0c;他的每个结点增加⼀个存储位来表⽰结点的颜⾊&#xff0c;可以是红⾊或者⿊⾊。通过对任何⼀条从根到叶⼦的路径上各个结点的颜⾊进⾏约束&#xff0c;红⿊树确保没有⼀条路径会⽐其他路径⻓出2倍&#xff0c;因…...

docker-compose——安装mongo

编写docker-compose.yml version : 3.8services:zaomeng-mongodb:container_name: zaomeng-mongodbimage: mongo:latestrestart: alwaysports:- 27017:27017environment:- MONGO_INITDB_ROOT_USERNAMEroot- MONGO_INITDB_ROOT_PASSWORDpssw0rdvolumes:- ./mongodb/data:/data/…...

Vue 3.0中响应式依赖和更新

响应式依赖和更新是Vue 3.0中最重要的机制&#xff0c;其核心代码如下&#xff0c;本文将结合代码对这个设计机制作出一些解释。 // 全局依赖存储&#xff1a;WeakMap<target, Map<key, Set<effect>>> const targetMap new WeakMap();// 当前活动的副作用函…...

uniapp|实现获取手机摄像头权限,调用相机拍照实现人脸识别相似度对比,拍照保存至相册,多端兼容(APP/微信小程序)

基于uniapp以及微信小程序实现移动端人脸识别相似度对比,实现摄像头、相册权限获取、相机模块交互、第三方识别集成等功能,附完整代码。 目录 核心功能实现流程摄像头与相册权限申请权限拒绝后的引导策略摄像头调用拍照事件处理人脸识别集成图片预处理(Base64编码/压缩)调用…...

JavaScript【7】BOM模型

1.概述&#xff1a; BOM&#xff08;Browser Object Model&#xff0c;浏览器对象模型&#xff09;是 JavaScript 中的一个重要概念&#xff0c;它提供了一系列对象来访问和操作浏览器的功能和信息。与 DOM&#xff08;Document Object Model&#xff09;主要关注文档结构不同&…...

[强化学习的数学原理—赵世钰老师]学习笔记02-贝尔曼方程

本人为强化学习小白&#xff0c;为了在后续科研的过程中能够较好的结合强化学习来做相关研究&#xff0c;特意买了西湖大学赵世钰老师撰写的《强化学习数学原理》中文版这本书&#xff0c;并结合赵老师的讲解视频来学习和更深刻的理解强化学习相关概念&#xff0c;知识和算法技…...

使用Spring Boot与Spring Security构建安全的RESTful API

使用Spring Boot与Spring Security构建安全的RESTful API 引言 在现代Web应用开发中&#xff0c;安全性是不可忽视的重要环节。Spring Boot和Spring Security作为Java生态中的主流框架&#xff0c;为开发者提供了强大的工具来构建安全的RESTful API。本文将详细介绍如何结合S…...

深入理解构造函数,析构函数

目录 1.引言 2.构造函数 1.概念 2.特性 3.析构函数 1.概念 2.特性 1.引言 如果一个类中什么都没有&#xff0c;叫作空类. class A {}; 那么我们这个类中真的是什么都没有吗?其实不是,如果我们类当中上面都不写.编译器会生成6个默认的成员函数。 默认成员函数:用户没有显…...

Day 16

目录 1.JZ79 判断是不是平衡二叉树1.1 解析1.2 代码 2.DP10 最大子矩阵2.1 解析2.2 代码 1.JZ79 判断是不是平衡二叉树 JZ79 判断是不是平衡二叉树 dfs 1.1 解析 1.2 代码 /*** struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* TreeNode(in…...

摄影构图小节

1、三分构图法 三分构图法即将画面横竖各分为三份&#xff0c;即九宫格形式。 将画面用两条竖线和两条横线分割&#xff0c;就如同是书写中文的【井】字。这样就可以得到4个交叉点&#xff0c;然后再将需要表现的重点放置在4个交叉点中的一个附近即可。 拍摄自然风光时&#xf…...

DAY 28 类的定义和方法

知识点回顾&#xff1a; 类的定义pass占位语句类的初始化方法类的普通方法类的继承&#xff1a;属性的继承、方法的继承 比如def、class这些定义的关键词后&#xff0c;必须有一个有占据缩进位置的代码块。 还有下面这些依赖缩进的语句&#xff0c;都可以用pass语句来占位 x 1…...

RAG数据处理:PDF/HTML

RAG而言用户输入的数据通常是各种各样文档&#xff0c;本文主要采用langchain实现PDF/HTML文档的处理方法 PDF文档解析 PDF文档很常见格式&#xff0c;但内部结构常常较复杂&#xff1a; 复杂的版式布局多样的元素&#xff08;段落、表格、公式、图片等&#xff09;文本流无…...

机器学习 day04

文章目录 前言一、线性回归的基本概念二、损失函数三、最小二乘法 前言 通过今天的学习&#xff0c;我掌握了机器学习中的线性回归的相关基本概念&#xff0c;包括损失函数的概念&#xff0c;最小二乘法的理论与算法实现。 一、线性回归的基本概念 要理解什么是线性回归&…...

蓝牙耳机什么牌子好?倍思值得冲不?

最近总被问“蓝牙耳机什么牌子好”&#xff0c;作为踩过无数坑的资深耳机党&#xff0c;必须安利刚入手的倍思M2s Pro主动降噪蓝牙耳机&#xff01;降噪、音质、颜值全都在线&#xff0c;性价比直接拉满。 -52dB降噪&#xff0c;通勤摸鱼神器 第一次开降噪就被惊到&#xff01…...