什么时候应该抛出异常?

时间:2010-11-02 00:10:12

标签: c++ exception

我正在制作一个c ++游戏gui lib,并想知道我何时应该抛出异常。现在,例如,如果我得到一个NULL指针,该函数将默默地失败。我应该抛出异常吗?它不会真正导致它崩溃。什么是抛出异常的好地方的例子?

感谢

4 个答案:

答案 0 :(得分:11)

这个问题的通常答案是你应该只在“特殊”情况下抛出异常。但是什么是特殊情况。一些例子:

  • 您无法控制的事件(例如内存不足,文件丢失)
  • 传递给您的方法的非法参数(即您指定的方法需要一个句柄,调用方传递null)

将异常作为应用程序正常流程的一部分抛出通常是一个坏主意,但同样由您来定义应用程序的正常流程是什么。但另一种看待它的方法是你的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;

异常解决了许多问题,但它们并未解决与错误处理/检测相关的所有问题。除了状态代码外,编写无效代码与异常一样可能。