try块和异常处理

91 阅读4分钟

在设计各种软件系统的过程中,处理程序中的错误和其他反常行为是最困难的部分之一。像通信交换机和路由器这类长期运行的交互式系统必须将90%的程序代码用于实现错误检测和错误处理。随着基于web的应用程序在运行时不确定性的增多,越来越多的程序员更加注重错误的处理。

异常就是运行时出现的不正常,例如运行时耗尽了内存或遇到意外的非法输入。异常存在于程序的正常功能之外,并要求程序立即处理。

在设计良好的系统中,异常是程序错误处理的一部分。当程序代码检查到无法处理的问题时,异常处理就特别有用,在这些情况下,检测出问题的那部分程序需要一种方法把控制权转到可以处理这个问题的那部分程序。错误检测程序还必须指出具体出现了什么问题,并且需要提供一些附加信息。

异常机制提供程序中错误检测与错误处理部分之间的通信,C++的异常处理中包括:

throw表达式(throw experssion),错误检测部分使用这种表达式来说明遇到了不可处理的错误,可以说,throw引发了(raise)异常条件。

try块(try block),错误处理部分使用它来处理异常。try语句块以try关键字开始,并以一个或多个catch子句(catch clause)结束。在try块中执行的代码所抛出(throw)的异常,通常会被其中一个catch子句处理。由于它们“处理”异常,catch子句也称为处理代码(handler)。

由标准库定义的一组异常类(exception class),用来在throw和相应的catch之间传递有关错误信息。

throw表达式

系统通过throw表达式抛出异常,throw表达式由关键字throw以及尾随的表达式组成,通常以分号结束,这样它就成为了表达式语句。throw表达式的类型决定了所抛出异常的类型。

标准异常

C++标准库定义了一组类,用于报告在标准库中的函数遇到的问题。程序员可在自己编写的程序中使用这些标准异常类。标准库异常类定义在四个头文件中;

1.exception头文件定义了最常见的异常类,它的类名是exception。这个类只通知异常的产生,但不会提供更多的信息。 2.stdexcept头文件定义了几种常见的异常类。

3.new头文件定义了bad_alloc异常类型,提供因无法分配内存而由new抛出的异常。

4.type_info头文件定义了bad_cast异常类型。

exception 最常见的问题

runtime_error 运行时错误:仅在运行时才能检测到的问题

range_error 运行时错误:生成的结果超出了有意义的值域范围

overflow_error 运行时错误,计算上溢

underflow_error 运行时错误,计算下溢

logic_error 逻辑错误:可在运行前检测到的问题

domain_error 逻辑错误:参数的结果值不存在

invalid_argument 逻辑错误:不合适的参数

length_error 逻辑错误:试图生成一个超出该类型最大长度的对象

out_of_range 逻辑错误:使用一个超出有效范围的值

使用预处理器进行调试

C++程序员会使用预处理变量来有条件地执行用于调试的代码。这种想法是:程序所包含的调试代码仅在开发过程中执行。当应用程序已经完成,并且准备提交时,就会将调试代码关闭。可使用NDEBUG预处理变量实现有条件的调试代码:

int mian()
{
    #ifndef NDEBUG
    cerr << "starting main" << endl;
    #endif
    //...
}

如果NDEBUG未定义,那么程序就会将信息写到cerr中。如果NDEBUG已经定义了,那么程序执行时将会跳过#ifndef和#endif之间的代码。

预处理器还定义了其余四种在调试时非常有用的常量:

__FILE__ 文件名
__LINE__ 当前行号
__TIME__ 文件被编译的时间
__DATE__ 文件被编译的日期