异常(C++)

  • 六、异常
    • 6.1 传统错误处理(如 C语言)
      • 6.1.1 通过函数返回值处理异常
      • 6.1.2 通过远程跳转处理异常
    • 6.2 C++的异常处理
      • 6.2.1 对传统错误处理的改造
    • 6.3 函数的异常说明
    • 6.4 标准异常类

六、异常

异常是指程序运行期间发生的不正常情况,如 new 无法获得所需内存、数组下标越界、运算溢出、除0错误、无效参数以及打开文件不存在灯。异常处理就是指对程序执行过程中产生的异常进行适当的处理,避免程序出现丢失数据或破坏系统运行等灾难性后果。

6.1 传统错误处理(如 C语言)

6.1.1 通过函数返回值处理异常

#include <iostream>
#include <cstdio>
using namespace std;class A{
public:A(void) {cout << "A () " << endl;}~A(void) {cout << "~A ()" << endl;}
};int fun3(){FILE* fp = fopen("./1.text", "r");if(fp == NULL)return -1;cout << "open 1.text successed" << endl;fclose(fp);return 0;
}int fun2(){A b;fun3();
}int fun1(){A a;fun2();
}
int main (void) {A a;fun1();return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy07$ ./a.out 
A () 
A () 
~A ()
~A ()

优点:函数调用路径中栈对象得到正确析构,不存在内存泄漏

缺点:错误流程处理复杂,代码臃肿

6.1.2 通过远程跳转处理异常

#include <iostream>
#include <cstdio>
#include <csetjmp>
using namespace std;jmp_buf env;class A{
public:A(void) {cout << "A () " << endl;}~A(void) {cout << "~A ()" << endl;}
};int fun3(){FILE* fp = fopen("./1.text", "r");if(fp == NULL)longjmp(env, -1); //跳转到setjmp位置执行cout << "open 1.text successed" << endl;fclose(fp);return 0;
}int fun2(){A b;fun3();
}int fun1(){A a;fun2();
}
int main (void) {if(setjmp(env) == 0){ //保存当前栈的快照fun1();} else {return -1;}return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy07$ ./a.out 
A () 
A ()

优点:不需要逐层判断,一步到位,代码精炼

缺点:函数调用路径中的栈对象失去析构机会,存在内存泄漏风险

6.2 C++的异常处理

对传统错误处理做出了改进:发扬优点,避免缺点。

C++引入了3个用于异常处理的关键字:try, throw, catch。try用于检测可能发生的异常,throw用于抛出异常,catch用于捕获并处理由throw抛出的异常。try-thow-catch构造了C++异常处理的基本结构,形式如下:

try{...if err1 throw xx1; //如果是错误1 就抛出xx1异常...if err2 throw xx2;//如果是错误2 就抛出xx2异常...if errn throw xxn;//如果是错误n 就抛出xxn异常
}
catch(type1 arg){...}
catch(type2 arg){...}
catch(typen arg){...}

6.2.1 对传统错误处理的改造

#include <iostream>
#include <cstdio>
//#include <csetjmp>
using namespace std;//jmp_buf env;class A{
public:A(void) {cout << "A () " << endl;}~A(void) {cout << "~A ()" << endl;}
};class FileErr{
private:string filename;int line;
public:FileErr(const string& name, int num){filename = name;line = num;}friend ostream& operator<<(ostream& os, FileErr& fe);
};ostream& operator<<(ostream& os, FileErr& fe) {  //输出重载os << fe.filename << ": " << fe.line << ": " << "file open failed" << endl;return os;
}int fun3(){FILE* fp = fopen("1.text", "r");if(fp == NULL) {throw FileErr(__FILE__, __LINE__);  //抛出异常//throw -1; //抛出异常}cout << "open 1.text successed" << endl;fclose(fp);return 0;
}int fun2(){A b;fun3();
}int fun1(){A a;fun2();
}
int main (void) {try{fun1();}catch(int err) {if(err == -1){cout << "handle file open failed" << endl;return -1;}}catch(FileErr fe){ //按类类型返回cout << fe << endl;}return 0;
}

注意:catch在进行数据异常类型匹配时,不会进行数据类型的默认转换,只有与异常类型精确匹配的catch块才会被执行。

6.3 函数的异常说明

当一个函数声明中不带任何异常描述时,它可以抛出任何异常。

C++允许限制函数能够抛出的异常类型,限制方法时在函数声明后面添加一个throw参数表,在其中指定函数可以抛出的异常类型。

int fun(int, char) throw(int, char);

函数fun被限定只允许抛出 int 和 char 类型的异常,当 fun 函数抛出其他类型的异常时,程序将被异常终止。

如果函数不允许抛出任何异常,只需要指定throw限制表为不包括任何类型的空表。

int fun(int, char) throw();
#include <iostream>
#include <cstdio>
#include <csetjmp>
using namespace std;class FileError{};
class MemoryError{};void func(void) throw(FileError, MemoryError){ //func() 函数里面只能抛出 FileError 和 MemoryError 类型的异常//throw FileError();//throw MemoryError();throw -1; //如果抛别的类型异常   就会终止改程序}
int main (void) {try{func();}catch(FileError& er){cout << "FileError err" << endl;}catch(MemoryError& er){cout << "MemoryError err" << endl;}catch(int err){cout << "int err" << endl;}return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy07$ ./a.out 
terminate called after throwing an instance of 'int'
Aborted (core dumped)

6.4 标准异常类

#include <iostream>
#include <cstdio>
#include <csetjmp>
using namespace std;class FileError : public exception{
public:virtual const char * what() const throw(){cout << "handle file failed" << endl;return "FileError";}
};
class MemoryError : public exception{
public:virtual const char * what() const throw() {cout << "handle memory failed" << endl;return "MemoryError";}
};void func(void) throw(FileError, MemoryError){ //func() 函数里面只能抛出 FileError 和 MemoryError 类型的异常throw FileError();//throw MemoryError();//throw -1; //如果抛别的类型异常   就会终止改程序}
int main (void) {try{func();}catch(exception& er){/** 这里就用到多态了,多态通过指针或引用指向的那个对象 就调用那个对象中的成员函数* 这样一改造,就不用写很多的catch捕获函数了 写一个就够了* */cout << er.what() << endl;}return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy07$ ./a.out 
handle file failed
FileError

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235569.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于web3+solidity的众筹项目

基本配置&#xff1a;node、npm、yarn&#xff0c;安装ganache&#xff0c;chrome&#xff0c;chrome安装插件MetaMask&#xff0c; 主要功能&#xff1a;目的是实现一个简单的众筹平台&#xff0c;允许用户发起筹款项目、捐款、提出使用资金请求以及证明人证明。 部分合约&…

语义解析:如何基于SQL去实现自然语言与机器智能连接的桥梁

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 语义解析 定义 作用 语义解析的应用场景 场景一&#xff1a; 场景二&#xff1a; 总结语…

数字孪生+可视化技术 构建智慧新能源汽车充电站监管平台

前言 充电基础设施为电动汽车提供充换电服务&#xff0c;是重要的交通能源融合类基础设施。近年来&#xff0c;随着新能源汽车产业快速发展&#xff0c;我国充电基础设施持续增长&#xff0c;已建成世界上数量最多、服务范围最广、品种类型最全的充电基础设施体系。着眼未来新…

强化学习4——动态规划初探

动态规划具体指的是在某些复杂问题中&#xff0c;将问题转化为若干个子问题&#xff0c;并在求解每个子问题的过程中保存已经求解的结果&#xff0c;以便后续使用。实际上动态规划更像是一种通用的思路&#xff0c;而不是具体某个算法。 在强化学习中&#xff0c;被用于求解值函…

Python基础(二十四、JSON和pyecharts)

文章目录 一、JSON1.JSON介绍2.JSON格式数据转化3.示例 二、pyecharts1.安装pyecharts包2.查看官方示例 三、开发示例 一、JSON 1.JSON介绍 JSON是一种轻量级的数据交互格式&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据&#xff08;就是字符串&#xff09;…

【REST2SQL】08 日志重构增加输出到文件log.txt

【REST2SQL】01RDB关系型数据库REST初设计 【REST2SQL】02 GO连接Oracle数据库 【REST2SQL】03 GO读取JSON文件 【REST2SQL】04 REST2SQL第一版Oracle版实现 【REST2SQL】05 GO 操作 达梦 数据库 【REST2SQL】06 GO 跨包接口重构代码 【REST2SQL】07 GO 操作 Mysql 数据库 原来…

微内核、宏内核、混合内核,三者到底有什么区别?

最近几年&#xff0c;随着国内大厂纷纷发布自研操作系统&#xff0c;大家对这些操作系统的出身和相貌吵得不可开交。然而&#xff0c;本文并不打算陷入这种无尽的争论之中。 在计算机技术的发展历程中&#xff0c;所有的技术都是在不断的迭代和发展中形成的&#xff0c;无论是…

软件测试|如何在 Python 中比较两个列表

简介 在Python中&#xff0c;比较两个列表是一个常见的任务&#xff0c;可以帮助你找出两个列表之间的差异、共同元素或其他关系。本文将详细介绍如何在Python中比较两个列表的不同方法&#xff0c;包括使用循环、集合操作和列表推导式等。 方法1&#xff1a;使用循环比较列表…

hadoop自动获取时间

1、自动获取前15分钟 substr(from_unixtime(unix_timestamp(concat(substr(20240107100000,1,4),-,substr(20240107100000,5,2),-,substr(20240107100000,7,2), ,substr(20240107100000,9,2),:,substr(20240107100000,11,2),:,00))-15*60,yyyyMMddHHmmss),1) unix_timestam…

生成式 AI 如何重塑软件开发流程和开发工具?

生成式AI正在重塑开发流程和开发工具&#xff0c;通过自动化和优化软件开发过程&#xff0c;提高开发效率和质量。它可以帮助开发人员快速生成代码、测试和部署应用程序&#xff0c;同时减少错误和缺陷。此外&#xff0c;生成式AI还可以帮助开发人员快速理解和解决复杂的技术问…

MySQL 5.7.35下载安装使用_忘记密码_远程授权

文章目录 MySQL 5.7.35下载安装使用_忘记密码_远程授权MySQL下载地址mysql安装点击安装&#xff0c;最好以管理员身份运行选择自定义安装选择64位勾选启动自定义产品执行点击同意点击下一步点击执行下一步配置数据库端口号设置登录密码&#xff0c;如果密码忘记&#xff0c;下面…

Fontfabric:一款字体与设计的完美结合

一、产品介绍 Fontfabric是一款由国际字体设计公司Fontfabric开发的字体设计软件。它提供了一整套完整的字体设计工具&#xff0c;让用户可以轻松地创建、设计和定制自己的字体。Fontfabric拥有丰富的字体库&#xff0c;包括各种风格和类型&#xff0c;能够满足用户在不同场景…

[linux]编译一个ko文件并运行

一、需求 有一段代码需要在运行时加载注入内核中&#xff0c;当用户层需要访问时可以提供内核态环境去运行。 二、c代码构建 // #include <errno.h> // #include <string.h> // #include <stdio.h> // #include <fcntl.h> // #include <stdlib.h…

Java中输入和输出处理(三)二进制篇

叮咚&#xff01;加油&#xff01;马上学完 读写二进制文件Data DataInputStream类 FilFeInputStream的子类 与FileInputStream类结合使用读取二进制文件 DataOutputStream类 FileOutputStream的子类 与FileOutputStream类结合使用写二进制文件 读写二进制代码 package 面…

盘活存量GPU资源 破局高校算力不足窘境

“凭啥做大模型的优先分配算力&#xff1f;人家1个人4块A800&#xff0c;我们10个人用2块3090&#xff01;这日子没法过了&#xff01;”听着团队成员们的吐槽&#xff0c;某国内顶尖高校非大模型团队带队的博士老W也颇为无奈&#xff1a;“我们虽然不是做大模型的&#xff0c;…

竞赛保研 基于深度学习的行人重识别(person reid)

文章目录 0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图 4 实现效果5 部分代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的行人重识别 该项目较为新颖&#xff0c;适合…

Unity报错:[SteamVR] Not Initialized (109)的解决方法

问题描述 使用HTC vive 头像进行SteamVR插件的示例场景进行测试&#xff0c;发现头显场景无法跳转到运行场景&#xff08;Unity 项目可以运行&#xff0c;仅出现警告&#xff09;。 具体如下&#xff1a; [SteamVR] Not Initialized (109) [SteamVR] Initialization failed…

STL源码阅读总结从小白到大神:vector

一、vector概述 vector的数据格式与array非常相似&#xff0c;两者的差别在于空间的灵活运用&#xff0c;array是静态空间&#xff0c;一旦配置内存空间就不容易更改原来的空间大小。而vector是动态空间&#xff0c;随着元素的加入&#xff0c;它的内部机制就会自动扩容以容纳…

【算法】基础算法001之双指针

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.数组分块&#xf…

NACHI机器人模拟示教器如何切换中文

前言 现在开始学习机器人的编程语言&#xff0c;那么要学习会用首先得用模拟示教器来学习&#xff0c;但是全是英文确实比较难受一些些&#xff0c;没有中文来的直观。所以摸透一下如何给示教器更换语言。 具体步骤 步骤一&#xff1a;将中文的汉化包下载下来。具体的下载链…