我正在与一群主要不是计算机科学或软件工程(主要是计算机工程)的开发人员建立代码基础
我正在寻找一篇关于何时应该捕获异常以及何时应该尝试从中恢复的好文章。我刚才发现一篇文章,我认为解释得很好,但谷歌并没有帮我找到它。
我们正在用C ++开发。文章的链接是一种可接受的答案形式,以及带有指针的摘要。我正在这里教书,所以教程格式会很好。正如非软件工程师可以访问的那样。感谢。
答案 0 :(得分:5)
Herb Sutter有excellent article可能对您有用。它没有回答您的具体问题(何时/如何捕获),但确实提供了处理特殊情况的一般概述和指南。
我在这里逐字复制了他的摘要
区分错误和 nonerrors。如果失败是一个错误 并且只有它违反了一个功能 能够满足其被监禁的人 先决条件,建立自己的 后置条件,或重建 不变的,它分担责任 维护。其他一切都不是 错误。
确保错误永远留给您 程序处于有效状态;这是 基本保证。提防 不变的破坏错误 (包括但不仅限于, 泄漏),这只是普通的错误。
更喜欢另外保证 要么最终状态要么是 原始状态(如果有错误, 操作被回滚)或 预定目标国家(如果没有 错误,操作已经提交); 这是强有力的保证。
更喜欢另外保证 操作永远不会失败。虽然 这对大多数人来说是不可能的 功能,它是必需的 析构函数和函数等函数 释放函数。
最后,更喜欢使用例外 而不是要报告的错误代码 错误。仅在使用时使用错误代码 不能使用例外(当你 不要控制所有可能的召唤 代码并不能保证它会 用C ++编写并使用。编译 相同的编译器和兼容编译 选项),以及条件 不是错误。
答案 1 :(得分:0)
阅读书中的“异常处理”一章
答案 2 :(得分:0)
可能this MSDN部分会帮助您......
答案 3 :(得分:0)
最简单的建议:
如果您不知道是否捕获异常,请不要抓住并让它流动,有人会在某一时刻。
关于例外的观点是它们非常特殊(想想std::bad_alloc
)。除了深度嵌套代码块(我不太喜欢)的“快速退出”的一些奇怪用法之外,只有当你碰巧发表一些你不知道如何处理的东西时才应该使用异常。
我们选择一些例子:
file = open('littlefile.txt', open.mode.Read)
对我来说,这似乎很明显,这可能会失败,并且在许多情况下。虽然报告失败的原因很重要(为了准确诊断),但我发现在这里抛出异常并不是一种好的做法。
在C ++中,我会编写如下函数:
boost::variant<FileHandle,Error> open(std::string const& name, mode_t mode);
该函数可以返回文件句柄(很棒)或错误(oups)。但是,由于它是预期的,现在更好地处理它。此外,它具有显性的巨大优势,查看签名意味着您知道会发生什么(不是谈论异常规范,而是一个破碎的功能)。
一般来说,我倾向于将这些函数视为find
函数。当你搜索某些东西时,预计搜索可能会失败,这里没有例外。
考虑一个关联容器的一般情况:
template <typename Key, typename Value>
boost::optional<Value const&> Associative::GetItem(Key const& key) const;
再次感谢Boost,我明确表示我的方法可能(或不)返回预期值。
ElementNotFound个例外。再举一个例子:用户输入验证预计会失败。一般而言,预计投入将是敌对/生病/错误。这里不需要例外。
另一方面,假设我的软件处理数据库,没有它就不可能运行。如果数据库抽象层失去与数据库的连接而无法建立新的连接,那么引发异常是有意义的。
我保留技术问题的例外情况(连接丢失,内存不足等等)。