异常安全:强烈保证 vs 基本保证

3

我现在正在学习C++,并涉及到异常安全的话题。我很确定我理解了四个不同级别的异常安全的含义。但是什么情况下强异常保证不适用而基本异常保证适用呢?


最终,异常保证机制的目的是确保对象处于一致的状态,以便可以安全地销毁对象(基本保证)或者在抛出异常时撤消对象上的所有操作,使对象恢复到先前的状态(强保证)。在必须按步骤更改对象、多个步骤已完成并且随后可能会抛出异常的情况下,强保证是不适用的(因此无法安全地撤消已完成的步骤,或者撤消这些步骤所需的时间/资源太高)。 - Peter
@Peter:基本保证下,异常抛出后销毁不是唯一的可能操作。基本保证最小限度允许调用没有前置条件的任何方法,例如在一个文件上调用 is_open() - John Zwinck
2个回答

1

强异常保证当然是很好的,如果没有其他考虑因素,它应该被提供。

但是,在某些情况下,提供强异常保证可能太昂贵、太复杂甚至是不可能的。以下是一些例子:

  • 排序。如果排序谓词失败了,你真的想要有逻辑和存储来恢复原始顺序吗?大多数使用情况不需要那样做。
  • 状态更改被记录在一个不可变的追加日志或日记中。也许你可以写一条记录说“取消这个操作”,但你不能删除已经写入的内容。
  • 内存已经重新分配并且数据已经移动。将数据移回其原始位置可能是没有意义的。例如,如果容器被调整大小,现有数据被移动,然后添加新记录失败,将其调整为以前的大小可能是浪费时间的,即使大小没有改变,保持新的更大容量可能是更容易的。

在所有这些情况下,基本异常保证仍然有用,可能更合适。它可能允许程序在有效状态下继续运行,例如通过向用户返回错误消息。


例如,您已经通过网络发送了一些数据,然后出现了异常,类似于“连接已丢失”,基本上在这种情况下,我们可以提供的基本保证就是继续处理已经丢失的数据块。 - Nusrat Nuriyev

0
例如,它可能是一种合并算法,通常也被排序算法使用。
Scott Meyers谈到了基本保证。
“一些函数向调用者保证,即使抛出异常,程序不变式仍然保持完整(没有数据结构被破坏),也没有资源泄漏。”
因此,在这里不变式术语非常重要,这就是为什么我决定额外加五分钱的原因。
另外,值得一提的是,不变式可以与整个类相关,这个类必须当然是一致的,而不是在每个语句之后,但至少在某些处理和计算数据的关键点上。可以有特殊的方法来检查是否是不变式。
从我的理解来看,强保证就像我们对内存进行快照一样,应该与以前一样,可能很少在用户空间应用程序中使用,并且也不应该有任何副作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接