C++ 异常处理机制详解
C 语言与 C++ 错误处理方式的对比及应用
在编程中,错误处理是不可避免的。传统的 C 语言和现代的 C++ 在处理错误上有着明显的区别,前者依赖返回错误码的方式,而后者则引入了更为灵活的异常机制。
一、C 语言传统的错误处理方式
1. 终止程序:assert
C 语言中最简单的错误处理方式之一是直接终止程序,例如使用 assert。当程序在运行时遇到不可恢复的错误(如除零、内存访问越界等),程序会被强制终止。这种方式虽然简单,但有明显的缺陷:
- 用户体验不佳:一旦程序遇到问题就立即崩溃,用户无法继续使用程序,特别是在遇到小问题时。
- 缺乏灵活性:程序员无法提供其他的错误处理路径,例如记录日志、尝试恢复等。
2. 返回错误码
另一种常用的处理方式是返回错误码。很多 C 语言的库都会通过返回一个整数值来表示函数的执行结果。具体的错误信息通常会被存储在全局变量 errno 中,程序员可以通过查阅 errno 的值来判断出错的具体原因。
示例代码:
int func() {
if (/* 错误发生 */) {
errno = EINVAL; // 设置错误码
return -1; // 返回错误
}
return 0; // 返回成功
}
缺点:
- 额外的错误处理负担:程序员需要手动检查每个函数调用的返回值,并根据
errno做出相应的处理。这增加了代码的复杂性和出错的可能性。 - 函数调用链复杂:如果错误在深层函数中发生,那么需要逐层返回错误,直到外层函数捕捉并处理,这导致代码难以维护。
例如:
- 下面这段伪代码我们可以看到 ConnectSql 中出错了,先返回给 ServerStart,ServerStart 再返回给 main 函数,main 函数再针对问题处理具体的错误。
- 如果是异常体系,不管是 ConnectSql 还是 ServerStart 及调用函数出错,都不用检查,因为抛出的异常会直接跳到 main 函数中 catch 捕获的地方,main 函数直接处理错误。
int ConnectSql() {
// 用户名密码错误
if (...) return 1;
// 权限不足
if (...) return ;
}
{
( ret = () < ) ret;
fd = ();
(fd < ) errno;
}
{
(() < ) ...
;
}









