try控制块和异常处理
1.异常就是运行时的异常现象,比如数据库连接失效或者遇到了不期望的输入——导致从程序的正常功能中离开。
2.当在程序中发现了一个程序本身无法解决的问题并且由于这个问题程序无法继续运行下去时就要用到”异常处理“。 在这种情况下,检测部分就要发送出错了而无法继续执行的信号。此外,检测部分需要在不知道程序的那一部分会 解决这个异常的情况下去发送问题信号。对发生了什么发了信号之后,检测部分就停止处理了。
3.一个程序中如果包含有可能引发异常的代码的话,那么程序中的另一部分就会包含有解决异常的部分。
4.异常处理就支持在检测部分和处理部分之间的相互合作。
5.在C++中,异常处理包括:throw expression,检测部分使用它来表示遇到了一些不能处理的事情。也称throw抛出了异常。
try blocks,以关键字try开始,以一个或多个catch子句结束。从try块中抛出的异常通常由catch子句来处理 。由于它们处理异常,catch子句也叫做异常处理。
exception classes异常类的集合,使用它来传递在throw和相关的catch中的发生的异常信息。
一、throw expression
1.组成:throw+异常;
2.通常后面都会跟着分号;,使它变成一个表达式语句。
3.异常类型1:runtime_error是标准库异常之一,定义在头文件stdexcept中,必须用string或C中的字符串对 它进行初 始化,字符串提供了关于发生的问题的信息。4.抛出一个异常会终止当前的函数转去执行能够处理这个异常的部分。
二、try块
1.形式:
try {
程序语句
} catch (异常声明) {
异常处理语句
} catch (异常声明) {
异常处理语句
} // ...
2.在try块后面是许多的catch子句的列表。
3.一个catch包含了三部分:(1)关键字catch。
(2)在括号里面的对象(可能没有命名)的声明。被称为“异常声明”。
(3)一个块。
4,当选中一个catch去执行时,与它相关的块就被执行了。
5.当catch执行完毕时,程序会在try块中的最后一个catch子句后面继续执行。
6.在库中的每一个异常都有一个名为what的函数,这个函数没有参数并且返回一个C语言风格的字符串(一个const char*)。
7.runtime_error的成员what返回了一个string的拷贝,用来初始化特定的对象。8.在复杂的系统中,程序在遇到异常之前可能要执行好多语句。
比如,一个try可能调用一个包含try的函数,这个函数也可能调用另一个包含try的函数,......。
9.在寻找处理程序时,与调用的时候是相反的。当抛出一个异常时,抛出这个异常的函数会被最先搜索。如果没有匹配的catch,这个函数就会终止。那么调用抛出这个异常的函数就会被第二个搜索,一次类推,直到找到一个合适的可以匹配的catch。如果没有找到任何匹配的catch,那么程序会转去执行一个名为terminate的库函数。这个函数的行为是系统独立的,但是能够保证终止程序的继续执行。
10.在没有定义try块的程序中如果发生了异常,执行方法和上述相同。因为如果没有try块,就没有处理程序。
11.如果程序没有try块但是又发生了异常,此时terminate就会被调用,然后程序会离开。12.要想写一个异常安全的代码是很困难的。
异常打断了程序正常的执行流。在异常发生的地方,调用者可能会做一些必要的估计,然后也会有一些其它的事情没有做到。通常,跳过程序的某一部分可能意味着有一个对象被留在了无效或者不完整的状态,或者有资源没有被释放,等等。程序可能在异常处理期间进行“清理”,这被称为“异常安全”。但是,写一个异常安全的程序是非常困难的。
有一些程序使用异常去简单地终止程序,当有异常发生时。这样的程序通常不用考虑异常安全问题。
一个进行异常处理并在处理后继续执行的程序,一定要不断地关注一个异常是否会发生,程序必须要做一些什么去确保对象是有效的,确保内存没有泄露,并且程序被保存到了一个合适的状态。
三、标准异常
C++的库里面定义了许多类,这些类能够指出程序遇到了什么问题。这些异常类也在我们写的程序中被使用 到。这些类被定义在四个头文件中:
(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:逻辑错误,使用了一个在有效范围外的值。
(3)new头文件。定义了bad_alloc异常类型,在后面介绍。
(4)type_info头文件。定义了bad_cast头文件,在后面介绍。
1.库异常类只有很少的操作。我们可以创建,复制和赋值任何异常类型的对象。
2.我们仅仅能采用默认的初始化方式初始化exception,bad_alloc,bad_cast对象。给这些异常类型的对象提供初始化是不可能的。
3.其它的异常类型有着相反的行为:我们能用一个string或者C风格的字符串来初始化这些对象,但是我们不能默认初始化它们。当我们创建这些异常类型的对象的时候,我们必须提供初始化。初始化会提供出出错信息。
4.异常类型中提供了一个名为what的操作。这个函数没有参数,返回类型为const char*,是一个指向C格式字符串的指针。这个C格式的字符串指针会提供发生的错误信息。
5.what返回的C格式的字符串的内容依赖于异常对象的类型。对于用string初始化的异常类型,what返回的是那个字符串。对于其它异常类型,what返回的字符串的值是随着编译器变化的。