异常处理

SyEic_L MVP++

程序错误通常包括:

  • 语法错误

  • 逻辑错误(或语义错误)

  • 运行异常:程序设计对程序运行环境考虑不周而造成的程序运行错误

    • 对于x/y,给y输入了0
    • 文件打开错误
    • 由内存空间不足导致的内存访问错误

    可以预料,但无法避免

    保证程序的鲁棒性(robustness),需要加一些对可能出现的异常进行预见性处理

异常处理策略

  • 就地处理
  • 异地处理

就地处理

常用:调用exit或abort终止程序执行

异地处理

通过函数的返回值,或指针/引用类型的参数,或全局变量把异常情况通知函数的调用者,由调用者处理异常。

不足:

  • 函数的返回值返回异常情况会导致正常返回值和异常返回值交织在一起,有时无法区分
  • 程序的可读性差

C++结构化异常处理机制

try:把有可能遭遇异常的代码构成一个try语句块

throw:如果try中发生异常,由throw抛出异常,之后操作不再进行

catch:抛出的异常通过catch来捕获并处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void f(char *filename)
{ ifstream file(filename);
if (file.fail())
throw filename; //产生异常对象,报告错误情况
int x;
cin >> x;
......
return 0;
}
int main()
{ char str[100];
......
try { f(str); }
catch (char *fn) //捕获异常
{ ...... //处理异常
}
...... //正常情况
}
  • try { <语句序列> }
  • throw <表达式>; //执行throw语句后,接在其后的语句将不再继续执行,而是转向异常处理
  • catch (<类型> [<变量>]) { <语句序列> } //catch要紧跟在try之后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void f()
{ ......
...throw 1;
......
...throw 1.0;
......
...throw "abcd";
.......
}

int g()
{ ......
try
{ f();
}
catch (int) //处理函数f中的throw 1;
{ <语句序列1>
}
catch (double) //处理函数f中的throw 1.0
{ <语句序列2>
}
catch (char *) //处理函数f中的throw "abcd"
{ <语句序列3>
}
<非catch语句>
}

异常处理的嵌套

当在内层的try语句的执行中产生了异常,则首先在内层try语句块之后的catch语句序列中查找与之匹配的处理,如果内层不存在能捕获相应异常的catch,则逐步向外层进行查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void f()
{ try
{ g();
}
catch (int)
{ ......
}
catch (char *)
{ ......
}
}

void g()
{ try
{ h();
}
catch (int)
{ ......
}
......
... throw 2; //由f捕获并处理
}

void h()
{ ......
... throw 1; //由g捕获并处理
or
... throw "abcd"; //由f捕获并处理
......
}

Assertion(断言)

assert(<表达式>);

  • assert执行时:
    • 如果<表达式>的值为true,程序继续正常执行。
    • 如果<表达式>的值为false,则它会:
      • 首先,显示出相应的表达式、该assert所在的源文件名以及所在的行号等诊断信息;
      • 然后,调用库函数abort终止程序的运行。

宏assert的实现

1
2
3
4
5
#ifdef  NDEBUG
#define assert(exp) ((void)0)
#else
#define assert(exp) ((exp)?(void)0:<输出诊断信息并调用库函数abort>)//可理解为替换语句
#endif
  • Title: 异常处理
  • Author: SyEic_L
  • Created at : 2025-04-10 08:31:49
  • Updated at : 2025-04-10 08:31:49
  • Link: https://blog.syeicl.vip/2025/04/10/异常处理/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments