C++ 异常处理

异常是在程序执行期间发生的意外事件。例如,

double divide_by_zero = 7 / 0;

以上代码会引发一个异常,因为一个数字不能被 0 整除。

在 C++ 中,处理这些类型错误的过程称为异常处理。

在 C++ 中,我们借助 trycatch 块以及 throw 关键字来处理异常。

  • try - 可能引发异常的代码
  • throw - 检测到错误时引发异常
  • catch - 处理 throw 关键字引发的异常的代码

注意: throw 语句不是必需的,特别是如果我们使用标准的 C++ 异常。


C++ 异常处理的语法

C++ 异常处理的基本语法如下所示

try {

    // code that may raise an exception
    throw argument;
}

catch (exception) {
    // code to handle exception
} 

在这里,我们将可能生成异常的代码放在 try 块中。每个 try 块后面都有一个 catch 块。

当发生异常时,throw 语句会引发一个异常,该异常会被 catch 块捕获。

catch 块不能在没有 try 块的情况下使用。


示例 1:C++ 异常处理

// program to divide two numbers
// throws an exception when the divisor is 0

#include <iostream>
using namespace std;

int main() {

    double numerator, denominator, divide;

    cout << "Enter numerator: ";
    cin >> numerator;

    cout << "Enter denominator: ";
    cin >> denominator;

try { // throw an exception if denominator is 0 if (denominator == 0) throw 0; // not executed if denominator is 0 divide = numerator / denominator; cout << numerator << " / " << denominator << " = " << divide << endl; } catch (int num_exception) { cout << "Error: Cannot divide by " << num_exception << endl; }
return 0; }

输出 1

Enter numerator: 72
Enter denominator: 0
Error: Cannot divide by 0

输出 2

Enter numerator: 72
Enter denominator: 3
72 / 3 = 24

上面的程序将两个数字相除并显示结果。但是,如果分母为 0,则会发生异常。

为了处理异常,我们将代码 divide = numerator / denominator; 放在 try 块中。现在,当发生异常时,try 块内的其余代码将被跳过。

catch 块捕获抛出的异常并执行其中的语句。

如果 try 块中的任何语句都没有生成异常,则会跳过 catch 块。

C++ try, throw and catch Statements
C++ 中 try、throw 和 catch 语句的工作原理

请注意,我们使用代码 throw 0; 抛出了 int 字面量 0

我们可以根据情况和我们想在 catch 块中执行的内容来抛出任何字面量、变量或类。

catch 参数 int num_exception 接收由 throw 语句传递的值,即字面量 0


捕获所有类型的异常

在异常处理中,了解我们的 try 语句中的代码可能发生的异常类型非常重要。

这样我们就可以使用适当的 catch 参数。否则,try...catch 语句可能无法正常工作。

如果我们不知道 try 块中可能发生的异常类型,那么我们可以使用省略号 ... 作为我们的 catch 参数。

try {
    // code
}
catch (...) {
    // code
} 

C++ 多个 catch 语句

在 C++ 中,我们可以为来自单个代码块的各种异常使用多个 catch 语句。

try {
    // code
} 
catch (exception1) {
    // code
} 
catch (exception2) {
    // code
} 
catch (...) {
    // code
}

在这里,如果发生 exception1,我们的程序就会捕获它。如果没有,如果发生 exception2,它就会捕获它。

如果发生既不是 exception1 也不是 exception2 的错误,那么将执行 catch (...) {} 中的代码。

注意事项

  • catch (...) {} 块应始终放在我们 try...catch 语句的末尾。这是因为此块捕获所有可能的异常并充当默认的 catch 块。
  • 在我们的代码中包含默认的 catch 块不是强制性的。

示例 2:C++ 多个 catch 语句

此程序将两个数字相除并将结果存储在数组元素中。此程序可能发生两种异常

  • 如果数组越界,即如果数组的索引大于数组的大小
  • 如果一个数除以 0

这些异常在多个 catch 语句中被捕获。

#include <iostream>
using namespace std;

int main() {
    
    double numerator, denominator, arr[4] = {0.0, 0.0, 0.0, 0.0};
    int index;
    
    cout << "Enter array index: ";
    cin >> index;
    
    try {
        
// throw exception if array out of bounds if (index >= 4) throw "Error: Array out of bounds!";
// not executed if array is out of bounds cout << "Enter numerator: "; cin >> numerator; cout << "Enter denominator: "; cin >> denominator;
// throw exception if denominator is 0 if (denominator == 0) throw 0;
// not executed if denominator is 0 arr[index] = numerator / denominator; cout << arr[index] << endl; }
// catch "Array out of bounds" exception catch (const char* msg) { cout << msg << endl; } // catch "Divide by 0" exception catch (int num) { cout << "Error: Cannot divide by " << num << endl; } // catch any other exception catch (...) { cout << "Unexpected exception!" << endl; }
return 0; }

输出 1

Enter array index: 5
Error: Array out of bounds!

这里,数组 arr 只有 4 个元素。因此,index 不能大于 3

在这种情况下,index5。所以我们抛出一个字符串字面量 "Error: Array out of bounds!"。此异常被第一个 catch 块捕获。

请注意 catch 参数 const char* msg。这表明 catch 语句将字符串字面量作为参数。

输出 2

Enter array index: 2
Enter numerator: 5
Enter denominator: 0
Error: Cannot divide by 0

这里,分母是 0。所以我们抛出 int 字面量 0。此异常被第二个 catch 块捕获。

如果发生任何其他异常,它将被默认的 catch 块捕获。

输出 3

Enter array index: 2
Enter numerator: 5
Enter denominator: 2
2.5

这里,程序运行没有任何问题,因为没有发生异常。


C++ 标准异常

C++ 为我们提供了许多标准异常,我们可以在异常处理中使用它们。其中一些显示在下表中。

异常 描述
std::exception 所有 C++ 异常的父类。
std::bad_alloc 当动态内存分配失败时抛出。
std::bad_cast 当尝试对无效类型执行 dynamic_cast 时由 C++ 抛出。
std::bad_exception 通常在抛出异常且无法重新抛出时抛出。

C++ 中还有许多其他标准异常。

这些异常定义在 exception 头文件中。

要了解更多信息,请访问我们的C++ 标准异常教程。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战