当前位置:   article > 正文

5.6 try语句块和异常处理_try csdn

try csdn


异常是指存在于运行时的反常行为,这些行为超出了函数正常功能的范围。典型的异常包括失去数据库连接以及遇到意外输入等。

当程序的某部分检测到一个它无法处理的问题时,需要用到异常处理。此时,检测出问题的部分应该发出某种信号以表明程序遇到了故障,无法继续下去了,而且信号的发出方无须知道故障将在何处得到解决。一旦发出异常信号,检测出问题的部分也就完成了任务。

如果程序中含有可能引发异常的代码,那么通常也会有专门的代码处理问题。例如,如果程序的问题是输入无效,则异常处理部分可能会要求用户重新输入正确的数据;如果丢失了数据库连接,会发出报警信息。

异常处理机制为程序中异常检测异常处理这两部分的协作提供支持。在C++语言中,异常处理包括:

  1. throw表达式,异常检测部分使用throw表达式来表示它遇到了无法处理的问题。我们说throw引发了异常。
  2. try语句块,异常处理部分使用try语句块处理异常。try语句块以关键字try开始,并以一个或多个catch子句结束。try 语句块中代码抛出的异常通常会被某个catch子句处理。因为catch子句“处理”异常,所以它们也被称作异常处理代码。
  3. 一套异常类,用于在throw表达式和相关的catch子句之间传递异常的具体信息。

throw表达式(异常检测)

程序的异常检测部分使用throw表达式引发一个异常。

语法:

throw 错误的类型(例如:runtime_error)(构造函数);

举个例子:

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

int main()
{
	int item1, item2;
	cin >> item1 >> item2;
	if (item1==item2)
	{
		throw runtime_error("Datas aren't same!");
	}
	else
	{
		cout << item1 + item2;
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这段代码中,如果两个item一样就抛出一个异常,该异常是类型runtime_error 的对象。抛出异常将终止当前的函数,并把控制权转移给能处理该异常的代码

类型runtime_ error 是标准库异常类型的一种,定义在stdexcept头文件中。我们必须初始化runtime_ error 的对象,方式是给它提供一个string对象或者一个C风格的字符串,这个字符串中有一些关于异常的辅助信息。

try语句块(异常处理)

try 语句的基本格式:

try{
program-statement
}catch(exception-declaration){
handler-statements
}catch(exception-declaration){
handler-statements
}
······

try语句块的一开始是关键字try,随后紧跟着一个块,这个块就像大多数时候那样是花括号括起来的语句序列。

跟在try 块之后的是一个或多个catch 子句。catch子句包括三部分:关键字catch、括号内一个(可能未命名的)对象的声明(称作异常声明,exception declaration)以及一个块。当选中了某个catch子句处理异常之后,执行与之对应的块。catch一旦完成,程序跳转到try语句块最后一个catch子句之后的那条语句继续执行。

try语句块中的program-statements 组成程序的正常逻辑,像其他任何块一样,program-statements可以有包括声明在内的任意C++语句。一如往常,try语句块内声明的变量在块外部无法访问,特别是在catch子句内也无法访问。

编写处理代码

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

int main()
{
	int item1, item2;
	cin >> item1 >> item2;
	if (item1==item2)
	{
		try
		{
			throw runtime_error("Data must refer to same ISBN");//1
		}
		catch (runtime_error err)//2
		{
			cout << err.what();//3
		}
	}
	else
	{
		cout << item1 + item2;
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

这里有三个值得注意的点:

  1. throw runtime_error(“Data must refer to same ISBN”);这一句是抛出异常是runtime_error当中的一个异常,并对其进行初始化。
  2. runtime_error err 将异常接受并且进行初始化给自己定义的一个变量。
  3. 异常处理对象.what()输出的是初始化时传入内部的值。

函数在寻找处理代码的过程中退出

在复杂系统中,程序在遇到抛出异常的代码前,其执行路径可能已经经过了多个try语句块。例如,一个try语句块可能调用了包含另一个try语句块的函数,新的try语句块可能调用了包含又一个try语句块的新函数,以此类推。

寻找处理代码的过程与函数调用链刚好相反。当异常被抛出时,首先搜索抛出该异常的函数。如果没找到匹配的catch子句,终止该函数,并在调用该函数的函数中继续寻找。如果还是没有找到匹配的catch 子句,这个新的函数也被终止,继续搜索调用它的函数。以此类推,沿着程序的执行路径逐层回退,直到找到适当类型的catch子句为止。如果最终还是没能找到任何匹配的catch子句,程序转到名为terminate 的标准库函数。该函数的行为与系统有关,一般情况下,执行该函数将导致程序非正常退出。对于那些没有任何try语句块定义的异常,也按照类似的方式处理:毕竟,没有try语句块也就意味着没有匹配的catch子句。如果一段程序没有 try语句块且发生了异常,系统会调用terminate函数并终止当前程序的执行。(这一段好好进行理解

但是实际上这个函数用不到,我们只要未进行定义的异常,都会自动进行退出。

例子:

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

int main()
{
	int item1, item2;
	cin >> item1 >> item2;
	if (item1==item2)
	{
		try
		{
			throw runtime_error("Data must refer to same ISBN");
		}
		catch (runtime_error err)
		{
			cout << err.what();
			terminate();
		}
	}
	else
	{
		cout << item1 + item2;
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

输出结果:
在这里插入图片描述

标准异常

C++标准库定义了一组类,用于报告标准库函数遇到的问题。这些异常类也可以在用户编写的程序中使用,它们分别定义在4个头文件中:

  1. exception头文件定义了最通用的异常类exception。它只报告异常的发生,不提供任何额外信息。
  2. stdexcept头文件定义了几种常用的异常类,详细信息如下表。
错误描述
exception最常见的问题
runtime_error只有运行的时候才能检测出的问题
range_error运行时错误:生成的结果超过了有意义的值域范围
overflow_error运行时错误:计算上溢
underflow_error运行时错误:计算下溢
logic_error程序逻辑错误
domain_error逻辑错误:参数对应的结果值不存在
invalid_argument逻辑错误,无效参数
length_error逻辑错误:试图创建一个超出该类型最大长度的对象
out_of_range逻辑错误:使用一个超出有效范围的值

但如果要自己写try的话我们都写runtime_error即可。剩下的自己理解一下,后面自己敲代码的时候出现这些错误,知道是什么错误即可。

  1. new头文件定义了bad alloc异常类型,这种类型将在之后进行介绍。
  2. type_ info头文件定义了bad_ cast异常类型,这种类型将在之后进行介绍。

what函数返回的字符串内容和异常处理对象的类型有关。如果异常处理类型有一个字符串初始值,则what返回该字符串。对于其他无初始值的异常类型来说,what返回的内容由编译器决定。

最后给一段代码大家理解一下:

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

int main()
{
	int item1, item2;
	cin >> item1 >> item2;
	if (item2==0)
	{
		try
		{
			throw runtime_error("除数不能为0");
		}
		catch (runtime_error err)
		{
			cout << err.what()<<endl<< "try again!"<<endl;
			cin >> item1 >> item2;
		}
	}
	cout << item1 / item2;
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

输出结果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/167005
推荐阅读
相关标签
  

闽ICP备14008679号