基础11C++中的异常处理以及swap
一、异常处理手段
-
抛出异常:throw 异常
-
作用:让调用者看见这个异常,如果调用者不理睬,就让调用者的调用者看见
-
-
接住异常: try {可能异常的code} catch(异常类型) {处理方式}
-
异常类型:一般为const &,防止copy;
-
如果 不确定异常类型,也可以用catch(...){处理方式},并且在catch中仍可用throw;继续抛
-
二、标准异常类
- 都继承于 exception 这个基类
- 异常的类型:
- bad_alloc
- logic_error
- length_error
- out_of_range (stl容器调用at)
- domain_error
- invalid_argument
- runtime_error
- range_error
- overflow_error
- underflow_error
- bad_cast
- catch(...)一般写在异常类型的最后
例子:
#include <iostream>
#include <vector>void strcpy(char *dest, const char *source)
{if (!dest || !source)throw std::invalid_argument("Null Pointers pass to strcpy.");while (*source)*dest++ = *source;*dest = '\0';
}template <typename T>
class Array
{
public:Array(std::size_t n)try : m_size(n), m_data(new T[n]){}catch (const std::bad_alloc &ba){std::cout << "No enough memory." << std::endl;throw;}private:size_t m_size;int *m_data;
};int main()
{char *dest = nullptr;const char *source = "hello";try{strcpy(dest, source);}catch (const std::invalid_argument &e){std::cout << "invalid_argument" << std::endl;std::cout << e.what() << std::endl;}catch (...){std::cout << "catch" << std::endl;}return 0;
}
三、栈展开

栈展开作用: 销毁局部变量
四、构造函数try-catch
template <typename T>
class Array
{
public:Array(std::size_t n)try : m_size(n), m_data(new T[n]) //写法比较特殊{}catch (const std::bad_alloc &ba){std::cout << "No enough memory." << std::endl;throw;}private:size_t m_size;int *m_data;
};
五、异常安全保证
- 不抛异常(Nothrow guarantee):保证不抛出异常
- 强异常安全保证(Strong guarantee):抛出异常程序状态不变
- 弱异常安全保证(Weak guarantee):状态改变,但在有效状态
六、不抛出异常 noexcept 关键字可以让编译器进行更好的优化
- 如果函数声明了noexcept, 但还是抛出了一场,调用栈可能开解(直接崩溃)
- note:移动构造 和 移动赋值 不声明为noexcept,比那一期是不敢用的
- noexcept的两种特殊用法:
- noexcept(bool) : 相当于开关noexcept的作用,noexcept(true) = noexcept(bool);
- noexcept(noexcept(std::swap(thing,other.thing))) : 这个noexcept是一个表达式。根据内部函数是够抛异常决定返回true/false
七、copy&swap
#include <vector>
#include <string>
#include <iostream>// class Buffer
// {
// private:
// unsigned char *_buf;
// int _capacity;
// int _length;// public:
// explicit Buffer(int capacity) : _capacity(capacity), _length(0)
// {
// std::cout << "Buffer(int capacity)" << std::endl;
// // throw std::invalid_argument("=====");
// _buf = capacity == 0 ? nullptr : new unsigned char[capacity]{};
// }// ~Buffer()
// {
// std::cout << "~Buffer()" << std::endl;
// delete[] _buf;
// }// Buffer(const Buffer &buffer)
// {
// std::cout << "Buffer(const Buffer &buffer)" << std::endl;
// this->_capacity = buffer._capacity;
// this->_length = buffer._length;
// // throw std::invalid_argument("=====");
// this->_buf = new unsigned char[buffer._capacity];
// std::copy(buffer._buf, buffer._buf + buffer._capacity, this->_buf);
// }// Buffer(Buffer &&buffer) noexcept
// {
// std::cout << "Buffer(Buffer &&buffer)" << std::endl;
// this->_capacity = buffer._capacity;
// this->_length = buffer._length;
// this->_buf = buffer._buf;// buffer._buf = nullptr;
// buffer._capacity = 0;
// buffer._length = 0;
// }// Buffer &operator=(const Buffer &buffer)
// {
// std::cout << "Buffer &operator=(const Buffer &buffer)" << std::endl;
// if (this != &buffer)
// {
// this->_capacity = buffer._capacity;
// this->_length = buffer._length;
// delete[] this->_buf;
// throw std::invalid_argument("....");
// this->_buf = new unsigned char[buffer._capacity];
// std::copy(buffer._buf, buffer._buf + buffer._capacity, this->_buf);
// }
// return *this;
// }// Buffer &operator=(Buffer &&buffer) noexcept
// {
// std::cout << "Buffer &operator=(Buffer &&buffer)" << std::endl;
// if (this != &buffer)
// {
// this->_capacity = buffer._capacity;
// this->_length = buffer._length;
// delete[] this->_buf;
// this->_buf = buffer._buf;// buffer._buf = nullptr;
// buffer._capacity = 0;
// buffer._length = 0;
// }
// return *this;
// }// bool write(unsigned char value) noexcept
// {
// if (_length == _capacity)
// return false;
// _buf[_length++] = value;
// return true;
// }
// };class Buffer
{
private:unsigned char *_buf;int _capacity;int _length;public:explicit Buffer(int capacity) : _capacity(capacity), _length(0){_buf = capacity == 0 ? nullptr : new unsigned char[capacity];}~Buffer(){delete[] _buf;}friend void swap(Buffer &lhs, Buffer &rhs);Buffer(const Buffer &buffer) : _capacity(buffer._capacity),_length(buffer._length),_buf(_capacity == 0 ? nullptr : new unsigned char[_capacity]){std::copy(buffer._buf, buffer._buf + buffer._capacity, this->_buf);}Buffer(Buffer &&buffer) noexcept : Buffer(0){swap(buffer, *this);}Buffer &operator=(Buffer buffer) // 会做一次拷贝构造/移动构造,根据传入参数类型确定{swap(buffer, *this);return *this;}bool write(unsigned char value) noexcept{if (_length == _capacity)return false;_buf[_length++] = value;return true;}
};void swap(Buffer &lhs, Buffer &rhs)
{using std::swap;swap(lhs._buf, rhs._buf);swap(lhs._capacity, rhs._capacity);swap(lhs._length, rhs._length);
}class BitMap
{
public:explicit BitMap(size_t size) : _buffer(size) {}static void Swap(BitMap &lhs, BitMap &rhs){using std::swap;swap(lhs._buffer, rhs._buffer);}private:Buffer _buffer;
};int main()
{int *a = nullptr;Buffer buffer(10);buffer.write(52);buffer.write(37);Buffer buffer1(20);buffer1.write(20);buffer1.write(111);swap(buffer, buffer1);// try// {// buffer1 = buffer;// }// catch (...)// {// std::cout << "error" << std::endl;// }// buffer.write(52);// buffer.write(37);// Buffer buffer1(20);// buffer1.write(20);// buffer1.write(111);// try// {// buffer1 = buffer;// }// catch (...)// {// std::cout << "error" << std::endl;// }// std::cout << "over" << std::endl;
}// Buffer buffer = Buffer(10);
// buffer = Buffer(16);
相关文章:
基础11C++中的异常处理以及swap
一、异常处理手段 抛出异常:throw 异常 作用:让调用者看见这个异常,如果调用者不理睬,就让调用者的调用者看见 接住异常: try {可能异常的code} catch(异常类型) {处理方式} 异常类型:一般为const &,防…...
写作词汇积累:得偿所望、可见一斑、搭腔
得偿所望 【得偿所望】是指经过长时间的期盼和努力,最终实现了自己的愿望或目标。 【得偿所望】强调了愿望实现后的满足感和成就感,是一个充满正能量和积极情感的词语。 【得偿所望】与【得偿所愿】在表达上也具有相似的含义,都指愿望得到了…...
android jetpack compose Model对象更新变量 UI不更新、不刷新问题
以前是搞老本行Android原生开发的,因为工作原因,一直在用vue小程序;因为一些工作需要,又需要用到Android原生开发,建了个项目,打开源码一看,天塌了!!!我以前的…...
数据库概论
目录 1、数据库管理系统(DBMS) 1.1 DBMS的主要功能 1. 数据库的定义功能 2. 数据库的操纵功能 3. 数据库的运行控制功能 4. 数据库的维护 5. 数据字典(Data Dictionary,DD) 2、数据模型 2.1 信息和数据(了解) 2.2 数据模型的三个层次 2.3 信息世界中的基…...
基于python使用UDP协议对飞秋进行通讯—DDOS
基于飞秋的信息传输 声明:笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 老规矩,封面在文末! 飞秋介绍 (…...
数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)
数据库管理275期 2024-12-25 数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)1 系统管理分片2 用户定义分片总结 数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225) 作者:胖…...
使用Streamlit部署机器学习模型
机器学习: 计算机能够从经验中学习,而无需明确编程。机器学习是目前最热门的领域之一,世界各地的顶级公司都在使用它来改善他们的服务和产品。但是没有使用在Jupyter Notebook中训练的机器学习模型。因此,我们需要部署这些模型&am…...
依图科技简介
依图科技(YITU Technology)是中国一家全球领先的人工智能(AI)公司,成立于2012年,总部位于上海。公司专注于计算机视觉、语音识别和自然语言处理等核心AI技术,致力于推动AI技术在医疗、安防、金融…...
苍穹外卖day07缓存部分分析
苍穹外卖Day07部分聚焦于缓存功能的实现与优化,通过引入redis缓存机制,结合Spring Cache 注解,降低了数据库负载,提升其响应速度。 以下是清除缓存功能代码: RestController RequestMapping("/admin/dish"…...
OCR实践-Table-Transformer
前言 书接上文 OCR实践—PaddleOCR Table-Transformer 与 PubTables-1M table-transformer,来自微软,基于Detr,在PubTables1M 数据集上进行训练,模型是在提出数据集同时的工作, paper PubTables-1M: Towards comp…...
HarmonyOS NEXT 实战之元服务:静态案例效果---电台推荐
背景: 前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考 先上本期效果图 ,里面图片自行替换 效果图1完整代码案例如下: Index import { authentica…...
微信小程序 不同角色进入不同页面、呈现不同底部导航栏
遇到这个需求之前一直使用的小程序默认底部导航栏,且小程序默认入口页面为pages/index/index,要使不同角色呈现不同底部导航栏,必须要在不同页面引用不同的自定义导航栏。本篇将结合分包(subPackages)展开以下三步叙述…...
MATLAB符号计算-符号表达式基础运算操作
1.1.2符号变量取值域的限定 默认复数域 【例1-1-2】解不等式 1.1.3创建符号表达式 对符号对象进行各种运算(算术运算、关系运算、逻辑运算),即可创建符号表达式。 1.算术运算与转置 【例1-1-3】 f5是f4的共轭转置 f6是f4的转置 2.关系…...
服务器被攻击怎么办
当服务器遭受恶意流量攻击,如DDoS(分布式拒绝服务)或CC(Challenge Collapsar)攻击时,传统的防护措施可能不足以应对。此时,采用高防IP服务可以有效缓解攻击压力,确保业务连续性和数据…...
精准识别花生豆:基于EfficientNetB0的深度学习检测与分类项目
精准检测花生豆:基于EfficientNet的深度学习分类项目 在现代农业生产中,作物的质量检测和分类是确保产品质量的重要环节。针对花生豆的检测与分类需求,我们开发了一套基于深度学习的解决方案,利用EfficientNetB0模型实现高效、准…...
【UE5 C++课程系列笔记】13——GameInstanceSubsystem的简单使用
目录 概念 基本使用案例 效果 步骤 概念 UGameInstanceSubsystem 类继承自 USubsystem,它与 GameInstance 紧密关联,旨在为游戏提供一种模块化、可方便扩展和管理的功能单元机制。在整个游戏运行期间,一个 GameInstance 可以包含多个 UGa…...
实用工具推荐----Doxygen使用方法
目录 目录 1 软件介绍 2 Doxygen软件下载方法 3 Doxygen软件配置方法 4 标准注释描述 4.1 块注释 和 特殊描述字符 4.1.1 函数描述示例 4.1.2结构体数组变量示例 特别注意: 4.2单行注释 4.2.1 单个变量注释示例 特别注意: 4.2.2对于枚举变量…...
js垃圾回收机制详细讲解
JavaScript 垃圾回收机制(Garbage Collection, GC)负责自动管理内存的分配和释放,确保程序在运行时不会因为内存泄漏而崩溃。它的主要任务是回收不再使用的内存空间,防止内存泄漏。JavaScript 的垃圾回收通常由引擎自动完成&#…...
【Linux/踩坑】Linux中启动eclipse或HDFS因JAVA_HOME设置报错
Linux中启动eclipse或hadoop因JAVA_HOME设置报错 eclipseHadoop eclipse 错误提示: A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No Java virtual machine was found after searching the follo…...
百度千帆平台构建AI APP的基础概念梳理
百度千帆平台构建AI APP的基础概念梳理 如果想制作大语言模型(LLM)相关的APP, 将利用百度的千帆平台在国内可能是最便捷的途径,因为百度开发了成熟的工作流,前些年还有些不稳定,现在固定下来了,…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
rknn toolkit2搭建和推理
安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
负载均衡器》》LVS、Nginx、HAproxy 区别
虚拟主机 先4,后7...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
