我正在讨论在新的C++项目中采用哪种方式.由于以下原因,我赞成对返回代码的异常(仅限特殊情况) -
这些是我从思考它和谷歌搜索中得出的要点.我必须承认,在过去的几年中,我倾向于使用C#工作的例外情况.请在退货代码上发布使用例外的进一步原因.对于那些喜欢返回代码的人,我也愿意倾听你的推理.谢谢
Nik*_*nić 47
我认为这篇文章总结了一下.
使用例外的参数
反对使用异常的参数
Gre*_*g D 10
我听说过更喜欢返回代码优于异常的最好情况就是这样:
凭借C#本身的大量近期经验,我可以理解你使用异常的愿望,但遗憾的是C++不是C#,而我们可以在C#中解决的很多事情在C++中最终都是致命的.
在Google的风格指南中可以找到支持和反对的案例的总结.简而言之:
优点:
- 例外允许更高级别的应用程序决定如何处理深层嵌套函数中的"无法发生"故障,而不会出现模糊且容易出错的错误代码簿记.
- 大多数其他现代语言都使用例外.在C++中使用它们会使其与其他人熟悉的Python,Java和C++更加一致.
- 一些第三方C++库使用异常,并在内部关闭它们使得与这些库集成更加困难.
- 异常是构造函数失败的唯一方法.我们可以使用工厂函数或Init()方法对其进行模拟,但这些方法分别需要堆分配或新的"无效"状态.
- 在测试框架中,例外非常方便.
缺点:
- 将throw语句添加到现有函数时,必须检查其所有可传递调用者.要么他们必须至少制定基本的异常安全保证,要么他们必须永远不会捕获异常,并对结果终止的程序感到满意.例如,如果f()调用g()调用h(),并且h抛出f catch的异常,则必须小心g或者可能无法正确清理.
- 更一般地说,异常使得程序的控制流程难以通过查看代码来评估:函数可能会返回您不期望的位置.这导致可维护性和调试困难.您可以通过一些关于如何以及在何处使用异常的规则来最小化此成本,但代价是开发人员需要了解和理解的更多内容.
- 异常安全需要RAII和不同的编码实践.需要大量的支持机制才能使编写正确的异常安全代码变得容易.此外,为了避免要求读者理解整个调用图,异常安全代码必须将写入持久状态的逻辑隔离到"提交"阶段.这将带来好处和成本(可能是您被迫混淆代码以隔离提交的地方).允许例外将迫使我们总是支付这些费用,即使它们不值得.
- 打开异常会为每个生成的二进制文件添加数据,从而增加编译时间(可能略微增加)并可能增加地址空间压力
- 异常的可用性可能会鼓励开发人员在不合适时抛弃它们,或者在不安全的情况下从中恢复.例如,无效的用户输入不应导致抛出异常.我们需要使样式指南更长时间来记录这些限制!
我建议阅读并理解利弊,然后根据这些来决定你自己的项目.你没有google所拥有的相同软件,所以对他们来说有意义的可能对你没有意义(这就是为什么我省略了他们的结论).
恕我直言,偏好返回代码的首要原因是你不能无声地忽略异常.这样做至少需要少量的额外代码.
对异常错误情况使用例外。您有一些很好的论据,我想提出一些反对意见。
首先,标准的C ++库本身就在各处使用异常。没有容器类或iostream,就不能使用它们。由于许多有用的功能将要使用它们,因此在没有它们的情况下尝试相处会带来很多问题。
其次,一旦学会了如何编写异常安全代码就不难了。它需要一致的RAII,但这仍然是您应该编写的方式。您应该采用构造提交方法,但这通常是一个优点,并且避免了一些细微的错误。(例如,自我分配问题通过复制交换方法完全消失了。)以我的经验,异常安全代码通常看起来更好。这是C ++程序员必须学习的东西,但是C ++程序员必须学习很多东西,而不仅仅是这些。
第三,如果您将例外限制在特殊情况下,则对性能的影响应最小。而且,正如Pavel Minaev指出的那样,如果您必须将错误代码返回结果,则可能会对性能产生影响,因为C ++并未设置为轻松返回多个值。
第四,确实很难使较旧的代码具有异常安全性。但是,这是一个新项目。
因此,我没有很好的理由在特殊情况下不抛出异常,也有很多理由这样做。