C++——异常检测与处理

try 语句块 和异常处理

异常是指存在于运行时的反常行为,这些行为超出了函数正常功能的范围。
典型的异常包括失去数据库连接以及遇到意外输入等。处理反常行为可能是设计所有系统最难的一部分。

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

C++ 提供了异常处理机制,用于对程序中异常检测异常处理这两个部分的协作提供支持。
包括:

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

throw表达式

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

#include
#include
using namespace std;

int main()
{
	int a;
	int b;
	cin >> a;
	cin >> b;
	if (a != b)
	{
		throw runtime_error("Date must refer to same");
		//程序执行到这里,表示 a 与 b 是不相同的
		//如果a b 不相同,通过 throw 表达式 就会抛出一个异常,这里这个异常类型为runtime_error
		//异常抛出将终止当前的函数,并把控制权转移给处理该异常的代码
		//这里初始化一个异常类型,就是给它提供一个string对象或者C风格的字符串,这个字符串中有一些关于异常的辅助信息
	}

	system("pasue");
	return 0;
}
  • 程序执行到throw表达式,表示 a 与 b 是不相同的
  • 如果 a b 不相同,通过 throw 表达式 就会抛出一个异常,这里这个异常类型为runtime_error,这是标准异常中的一种
  • 异常抛出将终止当前的函数,并把控制权转移给处理该异常的代码
  • 这里初始化一个异常类型,就是给它提供一个string对象或者C风格的字符串,这个字符串中有一些关于异常的辅助信息

try语句

try语句块原型:

try
{
	program-statement
}
	catch ( 异常声明1 )
	{
	异常处理代码1
	}
	catch ( 异常声明2 )
	{
	异常处理代码2
	}
	。。。
  • 当选中了某一catch子句处理异常后,执行与之对应的块。catch一旦完成,程序跳转到try语句块最后一个catch子句之后继续执行。
  • program-statement 可以有包括声明在内的任意C++语句,正常C++的逻辑,没有触发异常也跳转到try语句块最后一个catch子句之后继续执行。
  • try语句块内的声明的变量在块外部是无法访问的,特别是在catch子句内也无法访问。
#include
#include
using namespace std;

int main()
{
	int a;
	int b;
	cin >> a;
	cin >> b;
	
	try
	{
		if (a != b)
		{
			throw runtime_error("Date must refer to same");//发出异常信号
		}
	}
	catch (runtime_error err)//根据try的异常发出信号,进行异常处理
	{
		cout << err.what()//打印错误提示
			<< "\n Try Again? Enter y or n" << endl;
		char c;
		cin >> c;
		if (!cin || c=='n')//判断输入提示
		{
			system("pause");
			return 0;
		}
	}
	
	cout << "跳过异常处理" << endl;//无异常即跳转到这里

	system("pause");
	return 0;
}
  • 其中err.what()//打印错误提示,即what()为此异常类的成员函数,且每一个标准异常类都定义了名为what的成员函数,这些函数没有参数,返回值为C风格字符串(const *char)。
  • try语句块可嵌套
  • 注意且重要
    寻找处理代码的过程与函数调用链刚好相反。
    当异常被抛出时,首先搜索抛出该异常的函数。
    如果没找到匹配的 catch子句 ,就终止该函数,并在调用该函数的函数中继续寻找。
    如果仍然没有找到匹配的 catch子句,这个新函数也被终止,继续搜索调用它的函数。
    以此类推,沿着程序的执行路径逐层回退,直到找到适当类型的 catch子句为止。
    如果最终还是没有找到任何匹配的 catch子句,程序转到名为 terminate 的标准库函数。
    terminate函数的行为与系统有关,一般情况下,执行函数将导致程序非正常运行。

没有try语句块就意味着没有匹配的 catch子句。
如果一段程序没有try语句块且发生了异常,系统会调用 termiante函数并终止当前程序的执行。

标准异常

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

  • exception 头文件定义了最通用的异常类 exception。它只报告异常的发生,不提供任何额外信息。
  • stdexcept 头文件定义了几种常用的异常类。
  • new 头文件定义了 bad_alloc 异常类型。
  • type_info 头文件定义了 bad_cast 异常类型。

这里只讲一下stdexcept 头文件中几种常用的异常类:

异常类 说明
exception 最常见问题
runtime_error 只有在运行时才能检测出来的问题
range_error 运行时错误:生成的结果超出了有意义的值域范围
overflow_error 运行时错误:计算上溢
underflow_error 运行时错误:计算下溢
logic_error 程序路基错误
domain_error 逻辑错误:参数对应的结果值不存在
invalid_argument 逻辑错误:无效参数
length_error 逻辑错误:试图创建一个超出该类型最大长度的对象
out_of_range 逻辑错误:使用一个超出有效范围的值
  • 我们只能以默认初始化的方式初始化exception、bad_alloc、bad_cast对象,不允许给这些对象赋初值。
  • 其他类型相反,必须使用string或C风格字符串初始化对象不允许使用默认初始化方式。
  • 使用what函数返回错误提示

你可能感兴趣的:(C++学习,c++,异常处理)