有关C++的异常机制

news2024/11/26 4:28:02

目录

 为什么要有异常:

 异常的抛出和捕获:


 

 为什么要有异常:

        异常在C++用于错误处理,C语言中一般使用返回值表示错误,C++对于错误处理进行了拓展,统一使用异常机制来处理程序中发生的错误

        C++的异常处理包括两个部分----抛出异常和捕获异常,如果抛出的异常被捕获,处理完之后程序会继续运行,如果抛出的异常未被捕获,将导致程序终止

8eac10d2e68744c19085503ab2ba5552.png

 异常的抛出和捕获:

(1)抛出----throw

throw是用于抛出异常的关键字

throw 异常(对象)

在函数声明中应该指出可能抛出的异常

	void show();//该函数可能抛出任何异常
	void show()throw();//该函数不抛出任何异常
	void show()throw(char, int);//可能会抛出char类型和int型的异常

没有捕获的话,发生异常就会直接把程序干死,报出异常错误,如下代码示例:

void fun()throw(int, double, const char*)
{
	//可能会抛出int,double,const char*类型的错误
	srand((unsigned int)time(NULL));
	int s = rand() % 4;//0 1 2 3
	cout << "fun start" << endl;
	if (s == 0) {
		cout << "正常运行!" << endl;
	}
	else if (s == 1) {
		throw 1;//抛出int型异常
	}
	else if (s == 2) {
		throw 1.235;//爬出double型
	}
	else if (s == 3) {
		throw "错了错了";
	}
	cout << "fun over" << endl;
}
int main(int argc, const char** argv) {
	fun();

	return 0;
}

如果上面代码随机值取完rand后是1 2 3随便一个,他就会抛出异常,把程序干死,就像下面一样

8e795e71b9f04bc8a20f73a536674867.png

 运气好了取到0了那就正常退出咯

ee5ed34735dd453aaead6d18ae3b7f2f.png

那么我们写程序不可能明知道可能会有异常,把错误专门扔出来放着,让他把程序干死,我们肯定是需要一些去处理这个被抛出异常的方法的。

(2)那么就需要进行异常的捕获--------try.....catch

try {
		//可能抛出的异常的代码
	}
	catch (异常类型1 变量) {//根据类型捕获异常
		//处理异常类型2的代码
		//throw 变量----继续向上一层抛出
	}
    catch(...)//捕获任意类型的异常
    {
    }
    ...
	//异常捕获后,执行对应的异常处理代码,然后继续执行try...catch之后的代码
	//异常未被捕获,仍然导致程序终止
	//捕获异常后,如果当前无法处理,可以继续抛出
void fun()throw(int, double, const char*)
{
	//可能会抛出int,double,const char*类型的错误
	srand((unsigned int)time(NULL));
	int s = rand() % 4;//0 1 2 3
	cout << "fun start" << endl;
	if (s == 0) {
		cout << "正常运行!" << endl;
	}
	else if (s == 1) {
		throw 1;//抛出int型异常
	}
	else if (s == 2) {
		throw 1.235;//爬出double型
	}
	else if (s == 3) {
		throw "错了错了";
	}
	cout << "fun over" << endl;
}
int main(int argc, const char** argv) {
	try {
		//可能抛出的异常的代码
		fun();
		cout << "after fun!" << endl;
	}
	catch (int a) {//捕获int异常
		cout << "捕获到了int类型异常=" << a << endl;
	}
	catch (double b) {
		cout << "捕获到了double类型异常=" << b << endl;
	}
	catch (const char* p) {
		cout << "捕获到了const char*类型异常=" << *p << endl;
		cout << "无法处理!" << endl;
		throw p;
		//throw 变量----继续向上一层抛出
	}
	cout << "finished" << endl;
	return 0;
}

a8f323f3f3e749c7884226e4eb566bbe.png 0509a7f6cdf7479185c6e9cd6806826e.png

有可能单个的catch不能完全处理一个异常,在进行一些校正处理以后,希望再交给更外层的调用链函数来处理,catch则可以通过重新抛出将异常传递给更上层的函数进行处理。

就像上面我在处理const char*类型的时候,虽然捕获到了然后不能处理,throw扔出去,寻找外面能处理的函数去处理他,不过上面代码我就是简单的演示了一下扔出去,没有做处理

 

异常的抛出和匹配原则:

  • 异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。
  • 被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
  • 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。(这里的处理类似于函数的传值返回)
  • catch(…)可以捕获任意类型的异常,问题是不知道异常错误是什么。
  • 实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类对象,使用基类捕获,这个在实际中非常实用。

 在函数调用链中异常栈展开匹配原则:

  • 首先检查throw本身是否在try块内部,如果是再查找匹配的catch语句。如果有匹配的,则调到catch的地方进行处理。
  • 没有匹配的catch则退出当前函数栈,继续在调用函数的栈中进行查找匹配的catch。
  • 如果到达main函数的栈,依旧没有匹配的,则终止程序。上述这个沿着调用链查找匹配的catch子句的过程称为栈展开。所以实际中我们最后都要加一个catch(…)捕获任意类型的异常,否则当有异常没捕获,程序就会直接终止。
  • 找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行。

异常安全相关:
构造函数完成对象的构造和初始化,最好不要在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化

析构函数主要完成资源的清理,最好不要在析构函数内抛出异常,否则**可能导致资源泄漏(**内存泄漏、句柄未关闭等)

C++中异常经常会导致资源泄漏的问题,比如在new和delete中抛出了异常,导致内存泄漏,在lock和unlock之间抛出了异常导致死锁,C++经常使用RAII来解决以上问题。
 

实际开发中多鼓励使用异常,利大于弊!

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Myeclipse配置tomcat服务器

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a;国学周更-心性养成之路…

[附源码]Python计算机毕业设计Django的小说阅读系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

浅谈linux - 线程的基本应用

概述 线程&#xff08;英语&#xff1a;thread&#xff09;是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 注意 线程和进程之间的区别 1. 线程是执行的基本单位&#xff1b;进程是资源分配的基本单位。 2. 线程共享进程的资源…

【Eureka】【源码+图解】【七】Eureka的下线功能

【Eureka】【源码图解】【六】Eureka的续约功能 目录6. 下线6.1 shutdown()6.2 服务端cancel6.3 同步其他server节点6. 下线 主动下线方式 服务端&#xff1a;/eureka/apps/{application.name}/{instance-id}&#xff0c;以本系列文章的helloworld为例&#xff0c;发送DELETE…

程序员学习 CPU 有什么用?

本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 提问。 前言 大家好&#xff0c;我是小彭。 在上一篇文章里&#xff0c;我们聊到了计算机的冯诺依曼架构&#xff0c;以及计算机的五大部件&#xff1a;控制器、运算器、存储器、输入…

最全面的Spring教程(五)——文件上传与下载

前言 本文为 【SpringMVC教程】文件上传与下载 相关知识&#xff0c;具体将对使用MultipartResolver处理文件上传的步骤&#xff0c;两种文件下载方式&#xff08;直接向response的输出流中写入对应的文件流、使用 ResponseEntity<byte[]>来向前端返回文件&#xff09;等…

老油条表示真干不过,部门新来的00后测试员已把我卷崩溃,想离职了...

在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事&#xff0c;可遇不可求&#xff0c;向他学习还来不及呢。 真正让人反感的&#xff0c;是技术平平&#x…

降价背后,函数计算规格自主选配功能揭秘

作者&#xff1a;吴森梵&#xff08;仰森&#xff09; 在刚刚结束的 2022 杭州 云栖大会上&#xff0c;阿里云宣布函数计算 FC 开启全面降价&#xff0c;vCPU 单价降幅 11% &#xff0c;其他的各个独立计费项最高降幅达 37.5% 。函数计算 FC 全面降价&#xff0c;让 Serverle…

【Pandas数据处理100例】(七十五):Pandas的where()函数使用方法

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

线程篇(JAVA)

&#x1f495;前言&#xff1a;作者是一名正在学习JAVA的初学者&#xff0c;每天分享自己的学习笔记&#xff0c;希望能和大家一起进步成长&#x1f495; 目录 线程&#xff08;重点&#xff09; 第一种线程的实现 第二种线程的实现 线程的执行原理 线程的生命周期 休眠 …

醇酰基转移酶基因对猕猴桃酯生物合成的作用

文章信息 题目&#xff1a;Alcohol acyl transferase genes at a high-flavor intensity locus contribute to ester biosynthesis in kiwifruit 刊名&#xff1a;Plant Physiology 作者&#xff1a;Edwige J F Souleyre et al. 单位&#xff1a;New Zealand Institute for…

工业互联网数据监测预警解决方案

一、工业互联网数据安全趋势 随着“云、大、物、移、智”等新一代信息技术与制造业的融合发展&#xff0c;数字化生产、网络化协同、个性化定制、服务化延伸等生产运营模式逐渐成为常态&#xff0c;工业互联网数据不断走向开放流动。但原本封闭在工业现场的数据上网上云会带来…

论互联网公司的盈利能力

这个月&#xff0c;互联网公司三季度财报基本披露完毕。其中的共同点是都开始降本增效&#xff0c;提升盈利能力&#xff08;或者还在努力扭亏为盈&#xff09;。互联网公司基本是面向C端消费者的&#xff0c;京东创始人刘强东曾提出一个贯穿消费行业的“十节甘蔗”理论&#x…

[附源码]计算机毕业设计springboot健身房预约平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【剧前爆米花--爪哇岛寻宝】面向对象的三大特性——封装、继承以及多态的详细剖析(中——多态)。

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于Java面向对象三大特性——多态的文章&#xff0c;在本篇文章中我会分享多态的一些基础语法以及类在继承时代码的底层逻辑和执行顺序。 目录 多态的定义及实现条件 多态…

AWS动手实验 - 创建一个Web3网站

实验操作和录播 亚马逊云科技开发者社区 注意事项 按照操作手册进行即可&#xff0c;需要注意到的几个地方&#xff1a; 1&#xff1a;EC2 的 scale 可以不用设置为large那么高&#xff0c;small就够用了。 2&#xff1a;创建堆栈&#xff0c;是点击这个那个按钮&#xff0…

水土保持监测,无人机倾斜摄影该如何做?

水土监测在传统监测方法中存在着许多监测死角。近年来&#xff0c;随着无人机的普及&#xff0c;无人机倾斜摄影三维建模技术在水土保持领域发挥了巨大作用。 我国具有地形地貌范围广&#xff0c;地质情况复杂等特点&#xff0c;每年地质灾害造成很多人员伤亡和财产损失&#…

数商云SCM管理系统库存管理功能助力新能源汽车企业仓储管理更高效

在全球电动化浪潮下&#xff0c;新能源汽车近年来迎来快速发展&#xff0c;但同时&#xff0c;随之而来其面临的关键零部件供应链安全问题也愈来愈突出&#xff0c;新能源汽车供应链格局正在面临重塑&#xff0c;保障新能源汽车产业健康发展仍需持续发力。 随着国际形势突变&a…

Markdown基本语法

描述 Markdown 是一种轻量级的「标记语言」&#xff0c;可读、直观、学习成本低。 1. 强调 1.1 斜体&#xff08;单*、单_&#xff09; 例&#xff1a; *AlexYY* _AlexYY_ 效果&#xff1a; AlexYY AlexYY 1.2 加粗&#xff08;双*、双_&#xff09; 例&#xff1a; *Ale…

python常用代码总结2

1、列表的常规追加元素、追加列表操作 (1)列表追加多个元素&#xff0c;比如追加0-9 ls [] ls.extend(list(range(10)))ls Out[20]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (2)列表追加多个相同的元素&#xff0c;比如追加10个0 ls1 [] for i in range(10):ls1.append(0)ls1 Ou…