加载中...

怎样才能用好异常?

使用异常的准则

  1. 不允许被忽略的错误;
  2. 极少数情况下才会发生的错误;
  3. 严重影响正常流程,很难恢复到正常状态的错误;
  4. 无法本地处理,必须“穿透”调用栈,传递到上层才能被处理的错误。
    比如说构造函数,如果内部初始化失败,无法创建,那后面的逻辑也就进行不下去了,所以这里就可以用异常来处理。再比如,读写文件,通常文件系统很少会出错,总会成功,如果用错误码来处理不存在、权限错误等,就显得太啰嗦,这时也应该使用异常。相反的例子就是 socket 通信。因为网络链路的不稳定因素太多,收发数据失败简直是“家常便饭”。虽然出错的后果很严重,但它出现的频率太高了,使用异常会增加很多的处理成本,为了性能考虑,还是检查错误码重试比较好。

noexcept

noexcept 专门用来修饰函数,告诉编译器:这个函数不会抛出异常。编译器看到noexcept,就得到了一个“保证”,就可以对函数做优化,不去加那些栈展开的额外代码,消除异常处理的成本。

void func_noexcept() noexcept // 声明绝不会抛出异常
{
cout << "noexcept" << endl;
}

不过你要注意,noexcept 只是做出了一个“不可靠的承诺”,不是“强保证”,编译器无法彻底检查它的行为,标记为 noexcept 的函数也有可能抛出异常:

void func_maybe_noexcept() noexcept // 声明绝不会抛出异常
{
throw "Oh My God"; // 但也可以抛出异常
}

noexcept 的真正意思是:“我对外承诺不抛出异常,我也不想处理异常,如果真的有异常发生,请让我死得干脆点,直接崩溃(crash、core dump)。”所以,你也不要一股脑地给所有函数都加上 noexcept 修饰,毕竟,你无法预测内部调用的那些函数是否会抛出异常。

posted @ 2022-04-16 21:40  江上莲花香  阅读(78)  评论(0)    收藏  举报