浅析c++异常

异常处理:异常,让一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理这个问题。

传统错误处理办法

1、终止程序。(如段错误等)

2、返回错误码。

3、返回合法值,让程序处于某种非法的状态。(坑货)

4、调用一个预先设置的出现错误时调用的函数。

虽然可以解决问题,但都存在缺陷,然而引入异常处理可以很好的解决问题。

异常的抛出和捕获

1、异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个处理代码。

2、被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。

3、抛出异常后会释放局部存储对象,所以被抛出的对象也就还给系统了,throw表达式会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,异常对象在传给对应的catch处理之后撤销。

栈展开

抛出异常的时候,将暂停当前函数的执行,开始查找对应的匹配catch子句,本层没找到时就不断向外层寻找,若到达main函数的栈,依旧没有匹配的,则终止程序。

找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行。

具体实现如下:

#include<iostream>
using namespace std;
#include<string>

class Exception
{
public:
	Exception(int errId, const char* errMsg = "")
		:_errId(errId)
		, _errMsg(errMsg)
	{}
	void What()const
	{
		cout << "errId:" << _errId << endl;
		cout << "errMsg:" << _errMsg << endl;
	}
private:
	int _errId;//错误码
	string _errMsg;//错误信息
};
//异常的抛出
void Func1(bool isThrow)//抛出Exception对象
{
	if (isThrow)
		throw Exception(1, "抛出Exception对象");
	cout << "Func1->" << isThrow << endl;
}
void Func2(bool isThrowString,bool isThrowInt)//抛出string和int对象
{
	if (isThrowString)
		throw string("抛出string对象");
	if(isThrowInt)
		throw 7;
	cout << "Func2->" << isThrowString <<" "<<isThrowInt<< endl;
}

void Test()
{//异常的抛出
	try
	{   
		//Func1(true);Func2(true, true);此时只执行Func1(true),由于Func1()函数存在异常
		//同理针对下面程序,不执行Func2()的第二个参数的异常抛出
		//从调试中可以发现异常处理会跳出,造成程序执行中断
		Func1(false);
		Func2(true,true);
	}
	catch (const string& errMsg)
	{
		cout << "Catch string Object:" << errMsg << endl;
	}
	catch (int errId)
	{
		cout << "Catch int Object:" << errId << endl;
	}
	catch (const Exception& e)
	{
		e.What();
	}
	catch (...)
	{
		cout << "未知异常" << endl;
	}
	cout << "Func()" << endl;
}

异常的重新抛出

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

异常与构造函数&析构函数

1、构造函数完成对象的构造和初始化,需要保证不要在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化。

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

时间: 2024-08-19 13:03:17

浅析c++异常的相关文章

浅析Java异常

1.什么是异常 结构不佳的代码不能运行,这是Java的基本理念. 发现错误的理想时机是在编译期.然而,编译器并不能发现所有的错误,余下的问题就需要在程序运行时解决.这就需要错误能通过某种方式,把适当的信息传递给特定的接收者处理.Java中的异常处理的目的在于通过使用少量的代码来简化大型.可靠的程序的生成,通过此方式让你的应用中没有未处理的错误,而且它还带来了一个明显的好处:降低错误处理代码的复杂度. 异常,根据字面理解,有意外之意.把它置于代码层面来理解,即阻止了当前方法或作用域继续执行. 在J

[03] 为什么要使用异常机制

因为代码经验和见识等原因,说实话现在对于异常的使用,我也算是理解甚少.为什么用?什么时候用?即便是在查阅了部分资料以后,也只能在这里提炼出部分自己能够理解的,以供参考和讨论. 1.使用异常的好处 1.1 隔离常规代码和错误处理代码 实际上,我们希望程序不要出现问题,用户操作永远逻辑清晰而正确,一切都按照我们祈祷的那样运行,然而这是不可能的.必然会有错误必然会要我们去处理,但是错误的处理并不是我们代码的核心. 就像用户取钱的操作,我们核心的代码应该是账户金额变动和更新,而过程中可能出现的各种意外如

SQL Server事务遭遇网络异常时的处理机制浅析

SQL Server数据库中,如果应用程序正在执行一个事务的时候突然遭遇了网络异常,例如网络掉包,网络中断等,那么这个事务会怎么样? SQL Server数据库是通过什么机制来判断处理呢? 估计很多人跟我一样都有不少疑问, 我们下面构造一个测试实验来测试验证一下.如下所示: 步骤1:在客户端连使用SSMS工具连接到测试数据库,执行下面脚本,显性事务既不提交也不回滚.模拟事务正在执行当中. USE AdventureWorks2012; GO SELECT @@SPID; BEGIN TRAN D

C++中的异常浅析

我们都知道,无论是在C语言中还是C++的编程调试中,我们都会遇到各种各样的错误,那么在遇到这些错误的时候我们要怎么处理它们呢? 这里有一些传统的处理错误的方法: ①终止错误 ②返回错误码 ③返回合法值,让程序处于某种错误状态, ④调用一个预先设置好的处理错误的函数--->(回调函数) 为了更好地处理这一类问题,在C++中提出了异常,当函数出现一个自己无法处理的错误时,就会抛出异常,让函数的调用者直接或间接的来处理这个问题. 来举一个例子: 例1: 对于函数div来说,程序没有一种机制来处理当nu

【C++】 浅析异常

所谓异常,顾名思义就是不正常,有问题. 对于人来说有不正常的时候即生病身体不适,那么对于程序也一样,也有不正常即代码"有病". 那么,既然有病就要治疗,就要对症下药!这样才能恢复正常. 废了这么多话,还是引出我们C++的"异常"概念. 异常,让一个函数可以在发现自己无法处理的错误时抛出一个异常,希望它的调用者可以直接或者间接处理这个问题. 而传统的异常处理方法: 1.终止程序 2.返回一个表示错误的值(很多系统函数都是这样,例如malloc,内存不足,分配失败,返回

浅析arm的异常、中断和arm工作模式的联系

说到异常向量,会让人联想到中断向量.其实,中断是属于异常的子集的,也就是说中断其实是异常其中的一种. 回到异常向量,他其实是一张表格,每个格子里存放的是一个地址,或者是一个跳转命令,不管是哪个,其目的都是让PC跳转到真正处理异常的代码的地方. 以下是arm的异常向量表: 图1 初步介绍完异常向量,就来对比下ARM的arm的7种工作模式: 图2 User : 非特权模式,大部分任务执行在这种模式 FIQ :   当一个高优先级(fast) 中断产生时将会进入这种模式 IRQ :   当一个低优先级

浅析Java语言中两种异常的差别

Java提供了两类主要的异常:runtime exception和checked exception.所有的checked exception是从java.lang.Exception类衍生出来的,而runtime exception则是从java.lang.RuntimeException或java.lang.Error类衍生出来的. 它们的不同之处表现在两方面:机制上和逻辑上. 一.机制上  它们在机制上的不同表现在两点:1.如何定义方法;2. 如何处理抛出的异常.请看下面CheckedEx

阿里P7浅析Java虚拟机如何处理异常

Exceptions Exceptions允许您顺利处理程序运行时发生的意外情况.要演示Java虚拟机处理异常的方式,请考虑一个名为NitPickyMath的类.它提供了对整数执行加法,减法,乘法,除法和余数的方法.NitPickyMath在溢出,下溢和被零除的条件下抛出已检查的异常.Java虚拟机将在整数除零上抛出一个ArithmeticException,但不会在溢出和下溢上抛出任何异常.方法抛出的异常定义如下: class OverflowException extends Excepti

Python之encode与decode浅析

 Python之encode与decode浅析 在 python 源代码文件中,如果你有用到非ASCII字符,则需要在文件头部进行字符编码的声明,声明如下: # code: UTF-8 因为python 只检查 #.coding 和编码字符串,为了美观等原因可以如下写法: #-*-coding:utf-8-*- 常见编码介绍: GB2312编码:适用于汉字处理.汉字通信等系统之间的信息交换. GBK编码:是汉字编码标准之一,是在 GB2312-80 标准基础上的内码扩展规范,使用了双字节编码.