C++ 异常处理

2025 年 4 月 25 日 | 8 分钟阅读

在 C++ 中,异常处理是一种处理运行时错误的技术。它是一种用于处理程序执行期间发生的意外和不希望的事件的技术。异常处理的主要目的是即使在运行时错误之后也能处理应用程序的正常流程。

C++ 中,异常是在运行时抛出以显示错误的一个事件。大多数异常都派生自 std::exception 类,它是 C++ 标准库的一部分。如果异常未能有效维护,程序将打印一条错误消息并异常终止。

例如

这里,给定的代码会导致异常,因为不能将数字除以 0。

语法

它具有以下语法:

在此语法中,代码可以在 try 块内生成异常,并且每个 try 块后面都有一个 catch 块。如果代码中发生异常,throw 语句会抛出由 catch 块捕获的异常。

C++ 简单异常处理示例

让我们举一个例子来说明 C++ 中的异常处理。

示例

编译并运行

输出 1

Enter the Numerator Number: 8
Enter the Denominator Number: 0
Exception caught: Given number cannot be divided by zero!

输出 2

Enter the Numerator Number: 20
Enter the Denominator Number: 5
The Division Result is: 4

说明

在此示例中,我们使用了两个整数变量,Num(分子)和 Deno(分母)。之后,它要求用户输入分子和分母的值。如果分母为 0,它会抛出异常以防止除以 0。之后,catch 块处理异常并显示错误消息。如果没有错误,它会打印除法结果。

C++ 异常处理关键字

Cpp Exception handling 1

在 C++ 中,我们主要使用 3 个关键字来执行异常处理

  • try 块
  • throw 语句
  • catch 块

1. try 块

try 块用于识别可能导致错误的代码块。如果 try 块内发生异常,控制流将转移到 catch 块。

try 块的语法

它具有以下语法:

了解更多:Try/Catch 块

2. throw 语句

如果发生错误,我们可以使用 throw 发送错误消息或值。它是使用 throw 关键字执行的。

语法

它具有以下语法:

3. catch 块

catch 块接收由 throw 抛出的错误。它有助于修复或显示错误消息。它仅在 try 块中存在问题时运行。catch 关键字显示程序中的 catch 异常。

语法

它具有以下语法:

为什么在 C++ 中使用异常处理?

在 C++ 中,异常处理用于处理和响应程序中意外的运行时错误。在程序执行过程中,可能会发生多种错误,例如除以零、文件访问失败、无效输入等等。如果我们不使用异常处理,这些错误将导致程序终止并产生意外行为。

如果我们使用异常处理,我们可以使用 try、catch 和 throw 语句捕获这些错误。它通过将正常逻辑与错误处理逻辑分离来帮助提高代码可读性,从而使程序更健壮、用户友好且易于调试。

C++ 异常类

在 C++ 中,标准异常在 <exception> 类中指定,我们可以在程序中使用它。父子类层次结构的排列如下图所示

Cpp Exception handling

C++ 中的所有异常类都派生自 std::exception 类。现在,让我们看看 C++ 常见异常类的列表。

Exception描述
std::exception它是一个异常,也是所有标准 C++ 异常的父类。
std::logic_error它是一种可以通过读取代码检测到的异常。
std::runtime_error它是一种无法通过读取代码检测到的异常。
std::bad_exception它用于处理 C++ 程序中的意外异常。
std::bad_cast此异常通常由 dynamic_cast 抛出。
std::bad_typeid此异常通常由 typeid 抛出。
std::bad_alloc此异常通常由 new 抛出。

抛出异常

在 C++ 中,使用 throw 关键字抛出异常。当程序中抛出异常时,程序的正常执行停止,控制转移到可能处理异常的最近的 catch 块。如果在代码中没有找到 catch 块,程序将终止。

异常可以是任何有效的 C++ 对象,但通常,我们抛出标准异常类或用户定义异常的对象。

抛出异常示例

让我们举一个例子来说明 C++ 中抛出异常。

示例

编译并运行

输出

Caught an exception: Division by zero is not allowed!

说明

在此示例中,divide() 函数接受两个整数并检查除数是否为零。如果 b == 0,则使用 throw runtime_error("message") 抛出异常。main() 函数调用 divide(10, 0),这会导致异常。catch 块捕获异常并显示错误消息。

捕获异常

在 C++ 中,catch 块用于捕获程序中的异常。catch 块位于 try 块之后,并定义其处理的异常类型。可以使用多个 catch 块来处理多种类型的异常。

捕获异常示例

让我们举一个例子来说明 C++ 中捕获异常。

示例

编译并运行

输出

Caught an exception: Negative Number Exception
Caught an integer exception: 0
Caught an unknown exception

说明

在此示例中,testFunction() 函数包含一个 try 块,其中抛出不同类型的异常。之后,main() 函数使用不同的输入调用 testFunction() 以触发各种异常。

定义新异常

C++ 允许通过从 std::exception 派生来创建自定义异常类。它有助于更好地组织和处理不同类型的错误。

演示新异常示例

示例

编译并运行

输出

Caught custom exception: Custom Exception Occurred

说明

在此示例中,定义了一个自定义异常类 MyException,它继承自 std::exception。之后,重写 what() 函数以返回自定义错误消息。test() 函数抛出 MyException。main() 函数捕获异常并打印消息。

使用多个 catch 块示例

让我们举一个例子来说明如何在 C++ 中使用多个 catch 块。

示例

编译并运行

输出

Case 1 (Valid age):
Enter your age: 30  
Your age is: 30

案例 2(负年龄)

Enter your age: -10  
Error: Age cannot be negative.

案例 3(年龄过高)

Enter your age: 200  
Error: Age seems too high (200) - please enter a real age.

C++ 异常处理 MCQ

1. 下列哪个关键字用于在 C++ 中捕获异常?

  1. try
  2. throw
  3. catch
  4. finally
 

答案: c) catch


2. 下列哪项关于 C++ 异常处理的说法是正确的?

  1. 程序中只允许一个 catch。
  2. try 块后面必须至少跟一个 catch 块。
  3. 只能捕获内置异常。
  4. 每个程序都应该使用异常处理。
 

答案: b) try 块后面必须至少跟一个 catch 块。


3. 下列哪个选项是 C++ 中所有标准异常的基类?

  1. exception
  2. runtime_error
  3. erro_base
  4. logic_error
 

答案: a) exception


4. C++ 中异常处理的主要目标是什么?

  1. 用于处理语法错误。
  2. 用于维护逻辑错误
  3. 用于维护编译错误
  4. 用于处理运行时错误。
 

答案: d) 用于处理运行时错误。


5. C++ 中异常处理需要下列哪个标准头文件?

  1. <try>
  2. <exception>
  3. <error>
  4. <stdexcept>
 

答案: b) <exception>


下一个主题C++ try/catch