异常处理
-
概述
- 概念
- 异常是指在程序运行时发生的特殊情况,C++ 中提供了一套异常处理机制,标准库
提供了异常处理的基础
- 异常是指在程序运行时发生的特殊情况,C++ 中提供了一套异常处理机制,标准库
- 作用
- 异常提供了一种转移程序控制权的方式
- 与异常处理相关的关键字
- throw
- 用于标记可能抛出的异常的操作
- 当异常条件被触发时,程序会抛出(throw)一个异常,由 catch 捕获相应的异常,程序跳转到 catch 块定义的异常处理代码
- try
- 用于监测某个操作是否抛出异常
- try 块中的代码是可能抛出异常的代码,其后通常跟随一个和多个 catch 块用于在抛出异常的情况下处理异常
- catch
- 用于定义处理其前 try 块可能抛出的异常的代码
- 可以使用多个 catch 块分别处理不同的异常
- 也可以使用一个 catch 块处理所有的异常
- throw
- 概念
-
处理流程
- 异常处理的格式
-
标记异常
/** exceptionHandle() 函数为可能抛出异常的函数,需要使用 throw 关键字标记 */ void exceptionHandle() { // 在 condition 条件下抛出异常 if (condition) { throw exceptionInfo; } }
-
捕获异常
-
分别捕获不同的异常
try { // 可能抛出异常的代码 } catch(Exception1 e) { // 处理 Exception1 类型的异常 } catch(Exception2 e) { // 处理 Exception2 类型的异常 }
-
捕获所有的异常
try { // 可能抛出异常的代码 } catch(...) { // 处理 try 抛出的所有异常 }
-
-
- 异常处理的格式
-
示例
-
标记可能抛出的异常的操作
/** 除法函数 */ double division(double dividend, double divisor) { if (divisor == 0) { // 标记除 0 异常 throw "Division by zero condition!"; } return dividend / divisor; }
-
捕获并处理异常
int main(int argc, const char * argv[]) { // 定义相关的变量 double dividend = 250; double divisor = 0; double divisionResult; // 异常处理代码块 try { // 监测可能抛出的异常的操作 divisionResult = division(dividend, divisor); cout << divisionResult << endl; } catch (const char *exceptionInfo) { // 处理异常 cerr << exceptionInfo << endl; } return 0; }
-
此示例的异常处理结果如图
-
信号处理
-
概述
信号是由操作系统传递给进程的中断,会造成程序的提前终止。在 Terminal 中可以使用组合键 ctrl + C 产生中断。需要注意的是,并非所有的中断都可以被捕获。C++中的中断定义在头文件 <csignal>
-
信号
-
C++的头文件
定义了一下可捕获的中断信号 描述 ABRT FPE ILL INT SEGV TERM
-
-
相关函数
- 产生中断信号
-
函数原型
int raise(int sig); // sig 是要发送的信号编码
-
- 捕获中断信号
-
函数原型
void (*signal(int, void (*func)(int)))(int); /** sig:为信号的编码 func:为指向信号处理函数的指针 */
-
注意
- 在捕获中断信号前,必须使用 signal 函数注册
-
- 产生中断信号
-
示例
-
使用 raise 函数生成信号,使用 signal 函数捕获信号
// 中断处理函数 void signalHandle(int signalNumber) { cout << "Interrupt signal(" << signalNumber << ")received." << endl; exit(signalNumber); } // main 函数 int main(int argc, const char * argv[]) { int i = 0; // 注册中断信号与中断处理函数 signal(SIGINT, signalHandle); // 产生中断 while (++i) { cout << "Going to sleep..." << endl; if (i == 2) { raise(SIGINT); } sleep(1); } return 0; }
-