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

C++基础与深度解析 | 异常处理 | 枚举与联合 | 嵌套类与局部类 | 嵌套名字空间与匿名名字空间 | 位域与volatile关键字

文章目录

  • 一、异常处理
  • 二、枚举与联合
  • 三、嵌套类与局部类
  • 四、嵌套名字空间与匿名名字空间
  • 五、位域与volatile关键字

一、异常处理

  异常处理用于处理程序在调用过程中的非正常行为。

  • 传统的处理方法:传返回值表示函数调用是否正常结束。

    例如,返回 0 表示成功,非 0 表示失败。这种方法的缺点是函数的返回值被错误处理逻辑占用,不能用于其他目的。

    这种方法有局限性

  • C++ 中的处理方法:通过关键字 try/catch/throw 引入异常处理机制

    通过 try/catch/throw 引入了结构化的错误处理机制,使得错误处理逻辑与正常逻辑分离,提高了代码的可读性和可维护性。

    C++异常处理的关键组件

    • throw关键字

      throw 关键字用于抛出一个异常。它后面可以跟任意类型的表达式,该表达式的结果将被用作异常对象

    • try块

      try块包含了可能会抛出异常的代码。如果 try 块中的代码抛出了异常,那么与之匹配的 catch 块将被执行。

    • catch块

      catch块用于捕获并处理异常。可以有多个 catch 块来捕获不同类型的异常。

    • 异常类

      C++标准库中定义了一些基本的异常类,如 std::exceptionstd::runtime_errorstd::logic_error

异常触发时的系统行为—栈展开

  • 抛出异常后续的代码不会被执行

    一旦抛出异常,throw 语句之后的代码将不会被执行。控制流会立即转移到异常处理机制。

  • 局部对象会按照构造相反的顺序自动销毁

    在栈展开过程中,局部对象(包括由 new 分配的对象)会按照它们构造的相反顺序自动销毁。这是为了保证资源的正确释放,防止内存泄漏。

  • 系统尝试匹配相应的 catch 代码段

    • 如果找到匹配的 catch 块:

      • 执行 catch 块中的异常处理逻辑。
      • 异常被“捕获”后,catch 块之后的代码会继续执行。
    • 如果没有找到匹配的 catch 块:

      • 栈展开会继续进行,直到找到匹配的 catch 块或者退出当前函数。

      • 如果当前函数中没有找到匹配的

        块,栈展开会继续,直到:

        • 找到一个匹配的 catch 块。

        • 达到 main 函数。

          如果在 main 函数之前的所有函数中都没有找到匹配的 catch 块,程序将退出 main 函数。如果程序在退出 main 函数之前没有捕获到异常,std::terminate 函数将被调用。这通常会导致程序立即终止。

异常对象

  • 系统会使用抛出的异常拷贝初始化一个临时对象,称为异常对象
  • 异常对象会在栈展开过程中被保留,并最终传递给匹配的 catch 语句

try / catch语句块

  • 一个 try 语句块后面可以跟一到多个 catch 语句块(至少跟一个)

  • 每个 catch 语句块用于匹配一种类型的异常对象

    可以有多个catch块,每个用于处理不同类型的异常。

  • catch 语句块的匹配按照从上到下进行

    catch块按照它们在代码中出现的顺序(从上到下)进行匹配。一旦找到匹配的异常类型,就执行相应的catch块,忽略后面的catch块。

  • 使用 catch(…) 匹配任意异常

    catch(...)是一个通用的异常捕获器,它可以捕获任何类型的异常,包括未被前面的catch块捕获的异常。

  • 在 catch 中调用 throw 继续抛出相同的异常

    catch块中,可以使用throw;(不带参数)来重新抛出当前捕获的异常,这将导致继续搜索外层catch块。

示例:

#include <iostream>struct Str{};
struct Base{};
struct Derive : Base{};void f1()
{int x;Str obj;//throw Derive{}; //打印Derive exception is called in f2 throw Str{};  //打印exception is called in f2
}void f2()
{int x2;Str obj2;try{f1();}catch(Derive& e){std::cout << "Derive exception is called in f2 " << "\n";}catch(Base& e){std::cout << "Base exception is called in f2 " << "\n";}catch(...){std::cout << "exception is called in f2" << "\n";throw;  //重新抛出当前捕获的异常}std::cout << "other logic in f2.\n";
}void f3()
{try{f2(); }catch(Str& e){std::cout << "exception is called in f2" << "\n";}
}int main()
{f3();
}

在一个异常未处理完成时抛出新的异常会导致程序崩溃

  • 不要在析构函数或 operator delete 函数重载版本中抛出异常
  • 通常来说, catch 所接收的异常类型为引用类型

异常与构造、析构函数

  • 使用 function-try-block保护初始化逻辑

    在C++中,function-try-block允许你在函数的初始化列表和函数体中使用trycatch。这在构造函数中特别有用,因为它可以保护对象的初始化代码。

    示例:

    #include <iostream>struct Str
    {Str() { throw 100; }
    }class Resource {
    public:Resource() try : m_str(){}catch(int){std::cout << "Exception is catched at Resource::Resource" << std::endl;throw;}private:Str m_str;
    };int main()
    {try{Resource obj; }catch(int){std::cout << "Exception is catched at main" << std::endl;}
    }
    

    运行结果:

    Exception is catched at Resource::Resource
    Exception is catched at main
    
  • 在构造函数中抛出异常:

    • 已经构造的成员对象会被销毁

      如果在构造函数中抛出异常,已经构造的成员对象将按照它们构造的相反顺序自动销毁。

    • 类本身的析构函数不会被调用

      如果异常是在对象的构造过程中抛出的,并且没有被捕获,那么类的析构函数不会被调用。这是因为对象被视为未完全构造,因此析构函数不适用。

    • 局部对象的销毁

      如果对象是局部的(即在栈上),异常抛出时,局部对象会自动销毁,但不会调用其析构函数。

    • 动态分配对象的销毁

      如果对象是动态分配的(即使用new),在构造函数中抛出异常且未被捕获时,需要手动释放分配的内存,因为析构函数不会被调用。

描述函数是否会抛出异常

  • 如果函数不会抛出异常,则应表明,从而为系统提供更多的优化空间

    • C++ 98 的方式:
      • throw() :表明不会抛出异常
      • throw(int, char):表明可能抛出异常,显式给定了要抛出异常的类型
    • C++11 后的改进:
      • noexcept :表明不会抛出异常
      • noexcept(false):表明可能抛出异常,不需要显式给定会抛出哪种类型的异常
  • noexcept

    • 限定符:接收 false / true 表示是否会抛出异常
    • 操作符:接收一个表达式,根据表达式是否可能抛出异常返回 false/true
    • 在声明了 noexcept 的函数中抛出异常会导致 terminate 被调用,程序终止
    • 不作为函数重载依据,但函数指针、虚拟函数重写时要保持形式兼容

示例:

#include <iostream>void fun2()
{}void fun() noexcept(noexcept(fun2()))
{fun2();
}int main()
{std::cout << noexcept(fun()) << std::endl;
}

二、枚举与联合

三、嵌套类与局部类

四、嵌套名字空间与匿名名字空间

五、位域与volatile关键字

相关文章:

C++基础与深度解析 | 异常处理 | 枚举与联合 | 嵌套类与局部类 | 嵌套名字空间与匿名名字空间 | 位域与volatile关键字

文章目录 一、异常处理二、枚举与联合三、嵌套类与局部类四、嵌套名字空间与匿名名字空间五、位域与volatile关键字 一、异常处理 异常处理用于处理程序在调用过程中的非正常行为。 传统的处理方法&#xff1a;传返回值表示函数调用是否正常结束。 例如&#xff0c;返回 0 表示…...

番外篇 | 利用华为2023最新Gold-YOLO中的Gatherand-Distribute对特征融合模块进行改进

前言:Hello大家好,我是小哥谈。论文提出一种改进的信息融合机制Gather-and-Distribute (GD) ,通过全局融合多层特征并将全局信息注入高层,以提高YOLO系列模型的信息融合能力和检测性能。通过引入MAE-style预训练方法,进一步提高模型的准确性。🌈 目录 🚀1.论文解…...

python记录之字符串

在Python中&#xff0c;字符串是一种非常常见且重要的数据类型&#xff0c;用于存储文本信息。下面&#xff0c;我们将对Python字符串进行深入的讲解&#xff0c;包括其基本操作、常见方法、格式化以及高级特性。 1. 字符串的创建 在Python中&#xff0c;字符串可以通过单引号…...

Elasticsearch 认证模拟题 - 15

一、题目 原索引 task1 的字段 title 字段包含单词 The&#xff0c;查询 the 可以查出 1200 篇文档。重建 task1 索引为 task1_new&#xff0c;重建后的索引&#xff0c; title 字段查询 the 单词&#xff0c;不能匹配到任何文档。 PUT task1 {"mappings": {"…...

g++ 预处理 编译 汇编 链接 命令

g 预处理 编译 汇编 链接 命令 在命令行中使用 g 预处理、编译、汇编和链接源代码文件通常遵循以下步骤&#xff1a; 预处理&#xff08;Preprocessing&#xff09;&#xff1a;将源代码文件转换为经过预处理器处理的中间文件。 g -E source.cpp -o source.i 编译&#xff…...

计算机视觉中的low-level与 high-level任务

文章目录 low-level任务high-level任务区别联系others参考在计算机视觉领域中,low-level任务和high-level任务是两个重要的概念,他们分别涉及图像处理和分析的不同的层次。 low-level任务 low-level任务主要关注的是图像的底层特征,如颜色、纹理、边缘、形状等。通常涉及对…...

安徽京准NTP时钟系统:GPS北斗卫星授时下的生活重塑

安徽京准NTP时钟系统&#xff1a;GPS北斗卫星授时下的生活重塑 安徽京准NTP时钟系统&#xff1a;GPS北斗卫星授时下的生活重塑 时间的流逝自古以来时钟都是人类生活与活动的基础。然而&#xff0c;随着科技的进步&#xff0c;我们对时间管理和测量的方法已经发生了翻天覆地的变…...

图论第8天

685.冗余连接II 这题需要考虑两种情况&#xff1a; 1.两个输入 2.没有两个输入就是有成环 class Solution { public:static const int N 1005;int father[N];int n;void init(){for (int i 0; i < n; i){father[i] i;}}int find(int x){return x father[x] ? x : f…...

Python怎么配置环境变量:深度探索与实战指南

Python怎么配置环境变量&#xff1a;深度探索与实战指南 在Python编程的世界中&#xff0c;环境变量的配置是一个至关重要的步骤。它不仅影响着Python解释器的运行&#xff0c;还关系到各种第三方库和工具的使用。本文将带你深度探索如何配置Python的环境变量&#xff0c;并为…...

计网期末复习指南(六):应用层(DNS、FTP、URL、HTTP、SMTP、POP3)

前言&#xff1a;本系列文章旨在通过TCP/IP协议簇自下而上的梳理大致的知识点&#xff0c;从计算机网络体系结构出发到应用层&#xff0c;每一个协议层通过一篇文章进行总结&#xff0c;本系列正在持续更新中... 计网期末复习指南&#xff08;一&#xff09;&#xff1a;计算…...

HTML做成一个炫酷跳动爱心的页面

大家好&#xff0c;今天制作制作一个炫酷跳动爱心的页面&#xff01; 先看具体效果&#xff1a; 要创建一个炫酷跳动爱心的HTML页面&#xff0c;你可以使用HTML、CSS和JavaScript的组合。以下是一个简单的示例&#xff0c;它使用CSS动画和JavaScript来实现跳动效果。 首先&…...

React + SpringBoot实现图片预览和视频在线播放,其中视频实现切片保存和分段播放

图片预览和视频在线播放 需求描述 实现播放视频的需求时&#xff0c;往往是前端直接加载一个mp4文件&#xff0c;这样做法在遇到视频文件较大时&#xff0c;容易造成卡顿&#xff0c;不能及时加载出来。我们可以将视频进行切片&#xff0c;然后分段加载。播放一点加载一点&am…...

Suse Linux ssh配置免密后仍需要输入密码

【问题描述】 Suse Linux已经配置了ssh免密&#xff0c;但无法ssh到目标服务器。 对自身的ssh登陆也需要输入密码。 系统–Suse 15 SP5 【重现步骤】 1.使用ssh-keygen -t rsa生产key文件 2.使用ssh-copy-id拷贝public key到目标机器(或者自身) 3.配置成功后ssh 目标时仍需要输…...

apifox 生成签名

目录 前言准备编写签名脚本签名说明捋清思路编码获取签名所需的参数生成签名将签名放到合适的位置完整代码 在apifox中配置脚本新增公共脚本引用公共脚本添加环境变量 参考 前言 略 准备 查看apifox提供的最佳实践文章&#xff1a;接口签名如何处理 编写签名脚本 签名说明…...

介绍建造者模式

建造者模式 将一个复杂对象的创建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示 四种角色 Product 产品角色 指的是一个具体的产品对象Builder 抽象建造者 创建一个产品对象的各个部件的接口/抽象类ConcreteBuilder 具体建造者 实现或继承抽象建造者接口…...

【全部更新完毕】2024全国大学生数据统计与分析竞赛B题思路代码文章教学数学建模-电信银行卡诈骗的数据分析

电信银行卡诈骗的数据分析 摘要 电信银行卡诈骗是当前社会中严重的犯罪问题&#xff0c;分析电信银行卡交易数据&#xff0c;找出高风险交易特征&#xff0c;建立预测模型&#xff0c;将有助于公安部门和金融机构更好地防范诈骗行为&#xff0c;保障用户的财产安全。 针对问…...

【应用浅谈】Odoo的库存计价与产品成本(三)

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo的库存&#xff08;Stock&#xff09;模块拥有众多功能&#xff0c;其中库存计价是一项非常重要的功能&#xff0c;原生的成本方法分三种&#xff1a;【标准成本】&#xff0c;【平均成本】&#xff0c;【先进先出】&#…...

数据结构之ArrayList与顺序表(下)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 ArrayList的具体使用 118. 杨辉三角 扑克洗牌算法 接上篇&#xff1a;数据结构之ArrayLis…...

openi启智社区 aarch64 npu环境安装飞桨paddlepaddle和PaddleNLP(失败)

以前在启智社区都是编译安装飞桨&#xff0c;这回看到飞桨提供了npu安装包&#xff0c;兴冲冲的以为安装很简单。 之所以安装飞桨&#xff0c;是因为想在启智社区的启智大脑调试环境使用最新的PaddleNLP&#xff0c;结果报错&#xff1a;No module named paddle.nn.layer.laye…...

【漏洞复现】多客圈子论坛系统 httpGet 任意文件读取漏洞

0x01 产品简介 多客圈子论坛系统是一种面向特定人群或特定话题的社交网络&#xff0c;它提供了用户之间交流、分享、讨论的平台。在这个系统中&#xff0c;用户可以创建、加入不同的圈子&#xff0c;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...