【发布时间】:2009-10-22 23:50:14
【问题描述】:
假设我在每个级别都有嵌套方法 a、b、c、d、e,我们在正常操作过程中返回错误,但 e 也可能引发异常(例如 STL 插入时内存不足)。例外情况很少见,实际平仓发生的快/慢不是问题。
在这种情况下,最合适的异常处理策略是什么?
- 将其放入最低级别并转换为正常错误条件。
优点:不需要编写异常安全代码,实现最简单,最容易测试,最容易理解,展开所需的最少编译时间信息。
缺点:看起来不太酷,增加了明显的 try/catch 咔嗒声 - 几乎在每个 insert 和 push_back 周围,直到围绕 STL 容器编写异常安全包装器的程度,有人认为 try 块存在运行时性能损失(也有观点认为根本没有惩罚)。
- 在顶部处理它。
优点:看起来很酷,没有杂音。
缺点:很难直观地验证中间的所有代码确实是异常安全的,测试所有异常展开路径都将是
- 将其作为应用程序的完全重新启动处理最顶部:清除所有未被异常处理破坏的内容并重新启动
优点:可预测,可以容忍异常安全代码中的小瑕疵,比崩溃要好得多。
缺点:太苛刻了
- 编写自定义分配器,允许在深入调用堆栈之前检查 a() 处的内存保留。
void a()
{
...
x = b();
...
}
int b()
{
y = c();
...
return y + d();
}
int d()
{
...
z = e();
...
}
【问题讨论】:
-
我尝试格式化代码,但它不起作用,我不知道为什么..对不起。
-
它与列表后的代码有关。我只是添加了一个分隔符,我不知道有什么其他的修复方法。
-
也许你可以举一些例子说明你为什么认为:真的很难直观地验证中间的所有代码确实是异常安全的,以测试所有异常展开路径。例如,如果您使用范围对象,则无需担心它是如何展开的。
-
谢谢大家的帮助。我下定决心编写异常安全代码而不处理内部任何异常:在我的目标系统上,由于自定义 STL 分配器允许为最坏的情况预留 STL 分配器,异常确实非常不可能发生,在通用系统上,这种可能性仍然很低,因为为了减少内存需求和仔细编码,因此在调用者的代码中处理异常似乎非常合适。顺便说一句,这个讨论的可怕之处在于,显然没有编译器验证异常安全。