C++ 异常处理

Posted 我是小白呀

tags:

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

概述

作为一名专业写 Bug, 编程一天改 bug 一周的程序媛. 学会异常处理是非常重要的. 我们不仅要考虑没有错误的理想情况, 更要考虑存在错误时的情况.

在这里插入图片描述
Debug 可以帮助我们尽快发现错误, 消除错误. 错误类别:

  • 语法错误
  • 运行错误
  • 逻辑错误

异常处理

设计程序时, 事先分析程序运行时可能出现的各种意外情况, 定制出相应的处理方法. 异常处理指对运行时出现的差错以及其他例外情况的处理.

在这里插入图片描述
没有异常处理程序时, 运行出现异常, 程序只能终止运行. 设置了异常处理机制, 运行出现异常, 程序的流程就转到异常处理代码段处理. 用户可以指定进行任何的处理.

举一个除数为 0 的例子:

#include <iostream>
using namespace std;

template <typename T>
T Div(T x, T y);

int main() {
    // 声明变量
    int x, y;
    double x1, y1;

    // 赋值
    cin >> x >> y;
    cin >> x1 >> y1;

    // 输出商
    cout << x << "/" << y << "=" << Div(x, y) << endl;
    cout << x1 << "/" << y1 << "=" << Div(x1, y1) << endl;

    return 0;
}

template <typename T>
T Div(T x, T y) {
    return x / y;
}

输出结果:
在这里插入图片描述
众所周知分母不能为 0, 所以在这里我们可以看见程序终止运行了.

异常处理机制

我们把程序运行时的错误统称为异常. 对异常的处理统称为异常处理. C++ 中所提供的异常处理机制结构清晰, 在一定程度上可以保证程序的健壮性.

在这里插入图片描述

C++ 中处理异常的过程:

  • 在执行程序发生异常, 可以不在本函数中处理. 而是抛出一个错误信息, 把它传递给上一级的函数来解决. 上一级解决不了, 再传给其上一级, 由其上一级处理.
  • 如此主机上传, 直到最高一级还无法处理的话, 运行系统会调用 abort 终止程序.

格式:

try {
    被检查语句
    throw 异常
}
catch(异常类型1) {
    进行异常处理的语句1
}
catch(异常类型2) {
    进行异常处理的语句2
}
  • 把需要检查的语句放在 try 模块中
  • try 和 catch 作为一个整体出现
  • try 和 catch 块中必须用话括号括起来, 即使花括号内只有一个语句
  • 检查语句发生错误, throw 抛出异常, 发出错误信息
  • 由 catch 来捕捉异常信息, 并加以处理
  • 一个 try-catch 结构中只能有一个 try 块, 但却可以有多个 catch 块, 以便匹配不同的异常信息
  • 一般 throw 抛出的异常要和 catch 所捕获的异常类型所匹配
  • catch 后面的圆括号中, 一般只写异常信息的类型名, 如 catch (double)
  • 如果 throw 抛出异常信息找不到与之匹配的 catch 块, 那么系统就会调用一个系统函数 terminate, 使程序终止运行

函数声明指定异常

我们可以在函数声明中指定异常情况, 这样我们在看程序时能够知道所用的函数是否会抛出异常信息以及异常信息可能的类型. C++ 允许在声明函数时列出可能抛出的异常类型.

在这里插入图片描述
声明一个不能抛出异常的函数:

double triangle(double,double,double) throw();

声明一个能抛出异常的函数:

int triangle(int a, int b, int c) throw(runtime_error);

注: 要指定异常类型, 必须在声明和定义时都指定, 且类型相同.

练习

案例一

防止除数为 0:

#include <iostream>
using namespace std;

template <typename T>
T Div(T x, T y);

int main() {
    // 声明变量
    int x, y;
    double x1, y1;

    // 赋值
    cout << "Please enter two int:\\n";
    cin >> x >> y;
    cout << "Please enter two double:\\n";
    cin >> x1 >> y1;

    try {
        // 被检查的语句
        cout << x << "/" << y << "=" << Div(x, y) << endl;
        cout << x1 << "/" << y1 << "=" << Div(x1, y1) << endl;
    } catch (int) {  // 异常类型
        cerr << "除数为 0, 计算错误!" << endl;  // 异常处理数据
    } catch (double ) {  // 异常类型
        cerr << "除数为 0.0, 计算错误!" << endl;  // 异常处理数据
    }

    return 0;
}

template <typename T>
T Div(T x, T y) {
    if (y == 0){
        throw y;  // 抛出异常
    }

    return x / y;
}

输出结果:

Please enter two int:
1 2
Please enter two double:
2 0.0
除数为 0.0, 计算错误!
1/2=0
2/0=

案例二

求三角形周长, 防止三边小于零或组不成三角形.

#include <iostream>

using namespace std;

int triangle(int a, int b, int c);

int main() {
    // 声明变量
    int a, b, c;

    // 赋值
    cout << "Please enter the three side of the triangle:\\n";
    cin >> a >> b >> c;

    try {
        // 被检查的语句
        cout << "length of the triangle: " << triangle(a, b, c) << endl;
    } catch (const runtime_error &error) {  // 异常类型
        cerr << error.what() << endl;  // 异常处理数据
    }

    return 0;
}

int triangle(int a, int b, int c) {
    if (a <= 0 || b <= 0 || c <= 0) {
        throw runtime_error("The sides of the triangle cannot be less than or equal to zero");
    } else if (a + b <= c || a + c <= b || b + c <= a) {
        throw runtime_error("The lengths of three sides can't form triangle");
    }
    return a + b + c;
}

输出结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

C++异常处理:掌握高效健壮代码的秘密武器

使用源代码行信息处理 C++ 异常

C++异常处理的学习笔记

PCL异常处理:pcl 1.8.13rdpartyoostincludeoost-1_64oost ypeofmsvc ypeof_impl.hpp(125): error(代码片段

c++析构函数需要异常处理吗?如需要实现有何要求?

《c++徒步》基础语法篇