再探C++Primer(8)try语句块和异常处理

本文详细介绍了C++中的异常处理机制,包括try、throw和catch语句的使用方法,以及异常传播过程中的栈展开机制。文章还列举了C++标准库中定义的各种异常类型,并解释了运行时错误和逻辑错误的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

###try语句块#

异常处理部分使用try语句块来处理异常。try语句块以try关键字开始,以一个或多个catch子句结束。try语句块中,使用throw抛出的异常被catch捕获并处理。

其语法规则为:

try{
	program-statements
}catch(exception-declaration){
	handler-statements		
}catch(exception-declaration){
	handler-statements
}	//..

其中try语句块中的program-statements为正常语句块,exception-declaration为异常声明,handler-statements为捕获到异常后的异常处理语句。

###throw和catch#

C++里异常有两种

  • 一种是CPU发起的(比如非法内存访问等),强行中断当前执行的程序,并由运行环境执行适当的应对代码。 但是在windows环境下,如vc++中,底层直接是用的Win32异常来实现的,所以从操作系统上来看,全是Win32异常,并不会被c++的try/catch捕获。

  • 一种是C++里用throw语句抛出的异常,这个的结果只是一个单纯的跳转。

  • VC++如果编译的时候加/EHa参数 发生第一种异常的时候可以用C++的try/catch捕捉。

我们使用throw来抛出异常,用catch来捕获异常,如下举例:

double a,b;
while (cin<<a<<b){
	try{
		if (b != 0){
			a=a/b;
			cout<<a<<endl;
		}else{
			throw runtime_error("被0除");
		}
	}catch(runtime_error err){
		cout<<err.what()<<"\nTry again?(y or n)"<<endl;
		char c;
		cin<<c;
		if (!cin || c == 'n')
			break;
	}
}
  • **栈展开:**如果抛出的异常的函数调用语句位于一个try,则检查与该try关联的catch子句,如果找到了匹配的catch,就使用该catch来处理异常,否则如果该try包含在其他try块中,则继续检查与外层try匹配的catch子句,如果仍没有,则退出当前主调函数,继续在调用了该函数的其他函数中寻找,以此类推。如果最终没有catch匹配,则调用标准库函数terminate退出该程序;

  • **栈展开过程中对象被自动销毁:**块内局部对象会自动销毁,类类型对象会调用其析构函数;

  • **catch匹配类型:**允许throw非常量,catch捕获为常量;允许throw派生类,catch捕获为基类;数组被转换为指向数组(元素)类型的指针,函数被转换成直线该函数类型的指针;包括标准算数类型转换和类类型转换在内,其他所有转换规则都不能在匹配catch时使用;

  • **重新抛出:**当一个catch不能完整处理某个异常,可以将其重新抛出传递给另一个catch语句,重新抛出仍是一个throw语句,但是不包括任何表达式:throw;

  • **catch(...):**当使用catch来捕捉异常时,可以用catch(...)来捕获所有的异常。可以单独出现,也可以和其他的catch语句出现,如果catch(...)和其他的一起出现,则必须位于最后。

###C++中定义了一些标准异常:#

exception				//最常见的问题
runtime_error			//只有在运行时才能检测出的问题
range_error				//运行时错误:生成计算结果超出了有意义的值域范围
overflow_error			//运行时错误:计算上溢
underflow_error			//运行时错误:计算下溢
logic_error				//程序逻辑错误
domain_error			//逻辑错误:参数对应的结果值不存在
invalid_argument		//逻辑错误:无效参数
length_error			//逻辑错误:试图创建一个超出该类型最大长度的对象
out_of_range			//逻辑错误:使用一个超出有效范围的值
  • exception是C++标准库异常类继承层次中的基类,定义于exception头文件,我们自定义的异常类也要继承自exception,它只报告异常的产生,不提供任何额外信息;
  • 运行时错误由程序之外的事件造成,只有在运行时才能检测到;
  • 逻辑类错误是程序本身不正常时造成,例如无效实参或超出范围的实参。
  • 运行时错误和逻辑类错误定义于stdexcept头文件;

此外还有

  • new头文件中定义的bad_alloc类型,用于报告new操作符不能正确分配内存的情形;
  • type_info头文件中定义的bad_cast异常类型,dynamic_cast失败时,程序会抛出bad_cast异常类.

转载于:https://my.oschina.net/gjy19940115/blog/709011

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值