异常处理

Posted afreeman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异常处理相关的知识,希望对你有一定的参考价值。

异常处理的目的

让一个函数在发现了自己无法处理,或不知道如何妥善的最优化的处理的错误时,抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。 将问题检测和问题处理相分离。

在C语言的世界中,对错误的处理总是围绕着两种方法:一是使用整型的返回值标识错误;二是使用errno宏(可以简单的理解为一个全局整型变量)去记录错误。抛出异常是第三种更好的错误处理机制。

try catch

catch处理器的参数是引用,是throw出的异常对象,它并没有复制和创建新的异常对象。
catch处理器可以捕获异常并进行不彻底的异常处理,重新抛出异常。
try{ }语句块若没有抛出异常,try语句块执行完毕,忽略所有的catch处理器,继续往下执行。
try{ }语句块若抛出异常,说明try{ }语句块内调用了可能抛出异常的函数E,且函数E抛出了异常,
第一步:销毁函数E所有的局部变量。
第二步:暂停并跳出try语句块的执行流
第三步:逐一向下匹配catch处理器,遇到第一个该类或基类的异常引用,执行该catch处理器。
第四步:忽略剩下的所有catch处理器,紧接着执行最后一个catch处理下面的第一条语句。
如果没有匹配的处理器,会对try语句块所在函数进行堆栈展开。

堆栈展开

函数B是可能抛出异常的函数,函数A调用函数B,如果函数A没把函数B try并catch,那么函数A也变成了可能会抛出异常的函数。如果函数A把try{调用函数B的语句}catch(except &e),那么函数A是一个不会抛出异常的函数。

函数C抛出异常,销毁函数C的所有局部变量,如果函数B没有捕获C,销毁函数B的所有局部变量,如果调用函数B的函数A没有捕获异常,销毁函数B的所有局部变量,如果捕获了,则执行catch处理器。直至main函数,如果main函数也没捕获,则终止整个程序。

//Cat.h
#include<iostream>
class Cat{
private:
    int id;
public:
    Cat(int id) {
        this->id = id;
    }
    ~Cat() {
        std::cout << id << " cat is destroied\n";
    }
};
#include<iostream>
#include<stdexcept>
#include"Cat.h"
#include<cstdlib>
using namespace std;
void f3() {
    Cat c3(3);
    throw runtime_error("runtime_error in f3");
}
void f2() {
    Cat c2(2);
    f3();
}
void f1() {
    Cat c1(1);
    f2();
}
int main() {

    Cat c0(0);
    try {
        f3();
    }
    catch (runtime_error &e) {
        cout << e.what() << endl;
    }
    try {
        f1();
    }
    catch (runtime_error &e) {
        cout << e.what() << endl;
    }
    system("pause");
}

3 cat is destroied
runtime_error in f3
3 cat is destroied
2 cat is destroied
1 cat is destroied
runtime_error in f3
请按任意键继续. . .

 

以上是关于异常处理的主要内容,如果未能解决你的问题,请参考以下文章

使用片段中的处理程序时出现非法状态异常

Java异常处理机制

java 反射代码片段

java.util.MissingResourceException: Can't find bundle for base name init, locale zh_CN问题的处理(代码片段

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段

片段中的Android致命异常