@Dave Abrahams在他富有洞察力的论文《
错误和异常处理》中说:
如果可能的话,让你的异常类免受双重破坏。不幸的是,一些流行的编译器偶尔会导致异常对象被销毁两次。如果您可以安排它是无害的(例如通过将已删除的指针归零),您的代码将更加健壮。
我无法理解这个特定的指导方针,有人可以:
- 请提供这种双重破坏场景的代码示例 &
- 实现自定义异常类以避免这种情况的最佳方法是什么?
@Dave Abrahams在他富有洞察力的论文《
错误和异常处理》中说:
如果可能的话,让你的异常类免受双重破坏。不幸的是,一些流行的编译器偶尔会导致异常对象被销毁两次。如果您可以安排它是无害的(例如通过将已删除的指针归零),您的代码将更加健壮。
我无法理解这个特定的指导方针,有人可以:
就像@Tony 说的那样,该指南旨在防止编译器错误。该指南可以追溯到 2001 年左右,当时异常支持可能仍然有点不稳定。从那时起,我认为/希望大多数编译器已经修复了这个错误,因此该指南可能不再非常相关。
FWIW,该指南已从CERT 编码实践中删除。在本页的讨论中,提出了一个有趣的观点:两次破坏一个对象无论如何都是 UB,所以无论你在你的类中如何处理它都不会让你的程序完全可预测。
但是,如果您真的希望您的代码可以跨编译器(包括旧版本)移植,您可能应该考虑所有这些小故障。例如,Boost 通过大量工作来解决编译器错误;他们可以简单地编写符合标准的代码并将失败的责任推给实现,但这会阻碍他们的库的采用。
在编写代码时是否需要同样小心取决于您的要求,并且基本上可以归结为这个问题:支持数十个编译器真的值得付出所暗示的工作量吗?
引用@chrisaycock 的文章:
“为什么要毁灭两次”?由于编译器错误,这就是原因!这是一个错误,编译器不应该这样做。但他们确实如此。我曾在一个项目中使用 Sun 的 Studio8 编译器对此感到厌烦。我在 catch 子句中创建了一个 ostringstream 对象,发现它被破坏了两次。为了修复它,我在尝试之前将它移到了它,然后它起作用了。这种错误并不经常发生。大多数情况下,在 catch 子句中创建对象是可以的,但需要注意这一点。
问候,
安德鲁·马洛
标准中没有一个对象可以被破坏两次的情况。发生这种情况的任何实例都是代表用户的错误,或者,如果对象被编译器破坏(例如异常),则为编译器错误。在此之前,我从未在任何主要编译器中听说过这样的错误,并且没有理由相信这对于任何编写 C++ 代码的人来说都会有问题。