我正在制作一个c ++游戏gui lib,并想知道我何时应该抛出异常。现在,例如,如果我得到一个NULL指针,该函数将默默地失败。我应该抛出异常吗?它不会真正导致它崩溃。什么是抛出异常的好地方的例子?
感谢
答案 0 :(得分:11)
这个问题的通常答案是你应该只在“特殊”情况下抛出异常。但是什么是特殊情况。一些例子:
将异常作为应用程序正常流程的一部分抛出通常是一个坏主意,但同样由您来定义应用程序的正常流程是什么。但另一种看待它的方法是你的API应该指定它将接受的有效输入范围 - 你不应该抛出异常来响应这些输入。
此主题在本网站及其他地方已经涉及很多内容,因此使用您的标题进行谷歌搜索会引发更多示例和评论。
关于你的具体应用 - 也许可以获得一些其他游戏gui libs的api,以了解这些库的工作方式(假设你认为它们设计得很好)。
答案 1 :(得分:3)
非常一般:当异常发生时抛出异常。在您的示例中,如果null
是可接受的具有已定义行为的输入,则不会抛出异常。如果null
是非法输入,那么你应该抛出一个异常来向调用者表明出现了问题。
答案 2 :(得分:0)
这完全取决于您将来做什么以及您希望将来使用您的代码。
当某些事情失败并且您没有任何选择时,您应该抛出异常,或者从技术上讲,这对于尝试修复这种情况不是最佳的;换句话说,从你的角度来看是一个问题。
如果你谈论图书馆写作,我听到的是一个最糟糕的想法。
答案 3 :(得分:0)
你必须报告某种失败。您可以使用例外或状态代码执行此操作。就个人而言,我尽可能倾向于状态代码,尤其是在库代码中。
曾经有一段时间你不能确定实际上会捕获异常,除非执行捕获的代码是由相同编译器的相同版本构建的,其中标记与抛出异常的代码相同。这似乎已在很大程度上解决了具有事实上标准ABI的平台。但是,一旦我习惯于在没有例外的情况下报告库代码中的失败,我发现有充分的理由继续这样做。
首先,图书馆应该被第三方使用,而这些政党可能不会对writing exception safe code感到兴奋。
异常安全代码不仅仅与资源管理有关。考虑:
...
// m is a mutex
boost::scoped_lock(m); // now I can't forget to release the mutex
withdraw_money(acct1, 1000);
function_that_may_throw_exception();
deposit_money(acct2, 1000);
当然可以改写这个:
// using Boost SCOPE_EXIT
bool commit = false;
boost::scoped_lock(m);
withdraw_money(acct1, 1000);
SCOPE_EXIT((&commit) (&acct1))
{
if (!commit) {
deposit_money(acct1, 1000);
}
}
function_that_may_throw_exception();
deposit_money(acct2, 1000);
commit = true;
异常解决了许多问题,但它们并未解决与错误处理/检测相关的所有问题。除了状态代码外,编写无效代码与异常一样可能。