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

基础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;
};

五、异常安全保证

  1. 不抛异常(Nothrow guarantee):保证不抛出异常
  2. 强异常安全保证(Strong guarantee):抛出异常程序状态不变
  3. 弱异常安全保证(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

一、异常处理手段 抛出异常&#xff1a;throw 异常 作用&#xff1a;让调用者看见这个异常&#xff0c;如果调用者不理睬&#xff0c;就让调用者的调用者看见 接住异常: try {可能异常的code} catch(异常类型) {处理方式} 异常类型&#xff1a;一般为const &&#xff0c;防…...

写作词汇积累:得偿所望、可见一斑、搭腔

得偿所望 【得偿所望】是指经过长时间的期盼和努力&#xff0c;最终实现了自己的愿望或目标。 【得偿所望】强调了愿望实现后的满足感和成就感&#xff0c;是一个充满正能量和积极情感的词语。 【得偿所望】与【得偿所愿】在表达上也具有相似的含义&#xff0c;都指愿望得到了…...

android jetpack compose Model对象更新变量 UI不更新、不刷新问题

以前是搞老本行Android原生开发的&#xff0c;因为工作原因&#xff0c;一直在用vue小程序&#xff1b;因为一些工作需要&#xff0c;又需要用到Android原生开发&#xff0c;建了个项目&#xff0c;打开源码一看&#xff0c;天塌了&#xff01;&#xff01;&#xff01;我以前的…...

数据库概论

目录 1、数据库管理系统(DBMS) 1.1 DBMS的主要功能 1. 数据库的定义功能 2. 数据库的操纵功能 3. 数据库的运行控制功能 4. 数据库的维护 5. 数据字典(Data Dictionary&#xff0c;DD) 2、数据模型 2.1 信息和数据(了解) 2.2 数据模型的三个层次 2.3 信息世界中的基…...

基于python使用UDP协议对飞秋进行通讯—DDOS

基于飞秋的信息传输 声明&#xff1a;笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 老规矩&#xff0c;封面在文末&#xff01; 飞秋介绍 &#xff08;…...

数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)

数据库管理275期 2024-12-25 数据库管理-第275期 Oracle 23ai&#xff1a;画了两张架构图&#xff08;20241225&#xff09;1 系统管理分片2 用户定义分片总结 数据库管理-第275期 Oracle 23ai&#xff1a;画了两张架构图&#xff08;20241225&#xff09; 作者&#xff1a;胖…...

使用Streamlit部署机器学习模型

机器学习&#xff1a; 计算机能够从经验中学习&#xff0c;而无需明确编程。机器学习是目前最热门的领域之一&#xff0c;世界各地的顶级公司都在使用它来改善他们的服务和产品。但是没有使用在Jupyter Notebook中训练的机器学习模型。因此&#xff0c;我们需要部署这些模型&am…...

依图科技简介

依图科技&#xff08;YITU Technology&#xff09;是中国一家全球领先的人工智能&#xff08;AI&#xff09;公司&#xff0c;成立于2012年&#xff0c;总部位于上海。公司专注于计算机视觉、语音识别和自然语言处理等核心AI技术&#xff0c;致力于推动AI技术在医疗、安防、金融…...

苍穹外卖day07缓存部分分析

苍穹外卖Day07部分聚焦于缓存功能的实现与优化&#xff0c;通过引入redis缓存机制&#xff0c;结合Spring Cache 注解&#xff0c;降低了数据库负载&#xff0c;提升其响应速度。 以下是清除缓存功能代码&#xff1a; RestController RequestMapping("/admin/dish"…...

OCR实践-Table-Transformer

前言 书接上文 OCR实践—PaddleOCR Table-Transformer 与 PubTables-1M table-transformer&#xff0c;来自微软&#xff0c;基于Detr&#xff0c;在PubTables1M 数据集上进行训练&#xff0c;模型是在提出数据集同时的工作&#xff0c; paper PubTables-1M: Towards comp…...

HarmonyOS NEXT 实战之元服务:静态案例效果---电台推荐

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; Index import { authentica…...

微信小程序 不同角色进入不同页面、呈现不同底部导航栏

遇到这个需求之前一直使用的小程序默认底部导航栏&#xff0c;且小程序默认入口页面为pages/index/index&#xff0c;要使不同角色呈现不同底部导航栏&#xff0c;必须要在不同页面引用不同的自定义导航栏。本篇将结合分包&#xff08;subPackages&#xff09;展开以下三步叙述…...

MATLAB符号计算-符号表达式基础运算操作

1.1.2符号变量取值域的限定 默认复数域 【例1-1-2】解不等式 1.1.3创建符号表达式 对符号对象进行各种运算&#xff08;算术运算、关系运算、逻辑运算&#xff09;&#xff0c;即可创建符号表达式。 1.算术运算与转置 【例1-1-3】 f5是f4的共轭转置 f6是f4的转置 2.关系…...

服务器被攻击怎么办

当服务器遭受恶意流量攻击&#xff0c;如DDoS&#xff08;分布式拒绝服务&#xff09;或CC&#xff08;Challenge Collapsar&#xff09;攻击时&#xff0c;传统的防护措施可能不足以应对。此时&#xff0c;采用高防IP服务可以有效缓解攻击压力&#xff0c;确保业务连续性和数据…...

精准识别花生豆:基于EfficientNetB0的深度学习检测与分类项目

精准检测花生豆&#xff1a;基于EfficientNet的深度学习分类项目 在现代农业生产中&#xff0c;作物的质量检测和分类是确保产品质量的重要环节。针对花生豆的检测与分类需求&#xff0c;我们开发了一套基于深度学习的解决方案&#xff0c;利用EfficientNetB0模型实现高效、准…...

【UE5 C++课程系列笔记】13——GameInstanceSubsystem的简单使用

目录 概念 基本使用案例 效果 步骤 概念 UGameInstanceSubsystem 类继承自 USubsystem&#xff0c;它与 GameInstance 紧密关联&#xff0c;旨在为游戏提供一种模块化、可方便扩展和管理的功能单元机制。在整个游戏运行期间&#xff0c;一个 GameInstance 可以包含多个 UGa…...

实用工具推荐----Doxygen使用方法

目录 目录 1 软件介绍 2 Doxygen软件下载方法 3 Doxygen软件配置方法 4 标准注释描述 4.1 块注释 和 特殊描述字符 4.1.1 函数描述示例 4.1.2结构体数组变量示例 特别注意&#xff1a; 4.2单行注释 4.2.1 单个变量注释示例 特别注意&#xff1a; 4.2.2对于枚举变量…...

js垃圾回收机制详细讲解

JavaScript 垃圾回收机制&#xff08;Garbage Collection, GC&#xff09;负责自动管理内存的分配和释放&#xff0c;确保程序在运行时不会因为内存泄漏而崩溃。它的主要任务是回收不再使用的内存空间&#xff0c;防止内存泄漏。JavaScript 的垃圾回收通常由引擎自动完成&#…...

【Linux/踩坑】Linux中启动eclipse或HDFS因JAVA_HOME设置报错

Linux中启动eclipse或hadoop因JAVA_HOME设置报错 eclipseHadoop eclipse 错误提示&#xff1a; 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的基础概念梳理 如果想制作大语言模型&#xff08;LLM&#xff09;相关的APP&#xff0c; 将利用百度的千帆平台在国内可能是最便捷的途径&#xff0c;因为百度开发了成熟的工作流&#xff0c;前些年还有些不稳定&#xff0c;现在固定下来了&#xff0c…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...