C++简单的异常处理

异常

异常,是程序运行时不正确的状态。比如数组越界、整数除零等程序需要报错的状态。我们可以对异常进行捕捉和处理(使用try-catch语句块)。那么对异常进行捕捉和处理有什么好处呢?

我们用整数除零的例子来讲述。

首先看一个最为基础的例子:

#include <iostream>

using namespace std;

int main()
{
    cout << "输入两个数:" << endl;
    int a, b;
    cin >> a >> b;
    cout << "两数相除的结果为:" << a/b << endl;
    return 0;
}

输入4和2:

 

 

 但是输入4和0:

 

 可以看到,语句

cout << "两数相除的结果为:" << a/b << endl;

 并没有执行,并且程序返回了一个负数,说明程序运行时出现了错误而退出

这是因为整数不能够除0所导致的异常。如果我们后面还有很多代码,还要执行很多动作,那么在异常之后的语句都不会被执行了。也就是说,如果程序中出现了一处异常,会导致整个程序的崩溃。这显然不是程序员想看到的结果。

异常处理

我们使用异常处理机制,也就是捕捉和处理异常的try-catch语句来处理异常。在try-catch语句块中,try语句块用来捕捉异常,也就是说,在try语句块中的是一段有可能产生异常的代码段;而用catch语句块来处理异常,比如显示错误信息等。

如果发生了异常,try语句块会将异常捕捉并交给catch语句块处理,这样一来就避免了程序崩溃的情况,异常之后的程序仍可以运行。

加了异常处理的两数除法:

#include <iostream>
using namespace std;

int main()
{
    cout << "输入两个数:" << endl;
    int a, b;
    cin >> a >> b;
    try{
        if (b == 0) throw b;
        cout << "两数相除的结果为:" << a/b << endl;
    } catch (int ex) {
        cout << a << "不能除0" << endl;
    }

    return 0;
}

输入4和0:

 

 为了简单,我们这次直接抛出了一个int类型变量,但是在实际中,我们抛出的一般是异常类。

异常的抛出也可以写在函数里:

#include <iostream>
using namespace std;

int quotient(int a, int b) {
    if (b == 0) {
        throw b;
    }
    return a/b;
}
int main()
{
    cout << "输入两个数:" << endl;
    int a, b;
    cin >> a >> b;
    try{
        cout << a << "/" << b << "=" << quotient(a,b) << endl;
    } catch (int e){
        cout << a << "不能除0" << endl;
    }

    return 0;
}

思考:为什么使用异常处理机制

在上面的例子中,我们使用if语句也可以实现同样的效果

#include <iostream>
using namespace std;

int main()
{
    cout << "输入两个数:" << endl;
    int a, b;
    cin >> a >> b;
    if (b == 0) {
        cout << a << "不能除0" << endl;
    } else {
     cout << "两数相除的结果为:" << a/b << endl;
    }

    return 0;
}

那么我们为什么要“多此一举”使用异常处理呢?

比如我们存在着文件输入输出的异常,我们就没有办法去使用if语句来使程序正常运行了。

这只是理由之一,而更重要的是,if语句体现的是流程控制的思想,而异常处理体现的是一种对错误进行有效控制的思想。再者,使用if语句处理并不适合OOP,因为其语义不明显,不利于错误跟踪且类型单一。

if语句一般解决简单的逻辑错误,而异常处理是针对意外情况的。

在异常处理时,会允许一个函数向它的调用者(向上)抛出一个异常(如上面的例子中,quotient函数将其异常抛给调用它的main函数),让调用者处理异常。如果不具备异常处理的能力,函数就必须自己处理异常,或者程序停止运行。通常情况下,当错误发生时,被调用者,尤其是库函数,其自身并不知道如何处理。库函数可以检测到异常,但是只有调用者知道如何处理。

比如在发生文件的读写异常时,我们可以将异常抛给调用者,调用者决定下一步的动作是提示用户错误,还是直接报错,又或者执行其他的动作。而不是让被调用者本身处理错误。

异常处理的基本思想就是将错误检测(被调用者)和异常处理(调用者)分开。

posted @ 2020-05-01 21:06  川尘  阅读(335)  评论(0编辑  收藏  举报
`