你用什么C ++例外?

时间:2009-09-06 08:04:16

标签: c++ exception

可能的例外是最具争议的C ++功能。许多团队including google不使用它们。当然,是否使用它们的决定取决于上下文 - 例如,在某些游戏中,可能会在内存不足时崩溃,但在医疗设备控制软件中则不然。除了内存不足之外,一些团队可能会使用例外来解决网络中断,文件未找到等问题,但是其他人可能会说这太常见而不能被称为例外(其他人可能会说,但如果它很常见,那么?)

通常不使用异常的决定是基于可能被误导的论点,即很难编写异常安全的代码。有人说这个论点是错误的,因为使用错误代码的替代方法将导致至少同样困难的代码。大卫亚伯拉罕clarifies这一点。

在这个问题中,我很想知道:

  • 您在什么情况下使用例外?
  • 您申请的背景是什么?为什么你不能没有例外?
  • 您如何设法编写异常安全的代码?您必须进行多少投资?
  • 是/值得吗?

6 个答案:

答案 0 :(得分:22)

我使用异常来表示异常行为,而不是太频繁。当调试崩溃时,我经常使用break-on-exception,所以如果你的代码使用异常来处理通常发生的事情,我会悄悄地对你嗤之以鼻。当事情出乎意料地出错时使用它们。

可接受的示例:您的代码所依赖的服务器不可用,因此您的服务无法执行任何有意义的操作。

示例意味着我对您的代码感到恼火:用户输入的数字大于100,作为您的函数的输入,期望数字<= 100。

事实上,如果你正在开发一个面向用户的应用程序,那么用户可能不应该做任何产生异常的事情。

这是一个非常的灰色区域,如果您同意/不同意,请随时向我投票/投票。如果您不同意,请发表评论说明原因 - 我很想听听其他指南/规则/指标。

答案 1 :(得分:8)

对于真正特殊的情况,我通常是例外,但在决定什么是“特殊”时,我可能比大多数人都要高。

使这很难的原因是低级代码必须决定什么是异常,但只有高级代码知道给定的错误是否异常。例如,考虑一个加载图标的函数。失败后该怎么办?只有调用代码知道故障是否是关键的(程序需要该图标才能继续)(图标只是装饰性的)。

实际问题往往胜过优雅。失败的构造函数必须抛出异常才能使RAII工作。另一方面,析构函数不应该抛出异常。然后,所有障碍都不能让异常飞过。例如,在Windows中,让异常传播出OS回调(如窗口过程)是不安全的。如果你是多线程的,那么你的一个工作线程中的未处理异常将导致进程停止,而不会在其他线程上展开并调用d'tors。由于分页约束,设备驱动程序和内核代码通常不能使用C ++样式的异常。 COM不适用于例外情况。

答案 2 :(得分:7)

虽然很多人将C ++中的异常视为“发生异常事件”,但我发现它们也非常方便地进行基本的错误检查/验证,主要是在应用程序级别(因为不在应用程序级别)库)

示例,我宁愿写

try
{
  MethodA();
  MethodB();
  //.. a whole lot of other methods crucial to succeed for app initialization
}
catch( const SomeException& e )
{
  //show user the critical error contained in e
  return 1;
}

然后写

if( !MethodA() )
{
  //retrieve and show error
  return 1;
}
if( !MethodB() || !MethodC() )
{
  //retrieve and show error
  return 1;
}
//etc

这往往会导致更少的代码,也在方法本身内。

答案 3 :(得分:1)

几乎每个人都写代码可以抛出异常。他们遍布标准库。鉴于此,我不认为“不例外”政策是一个好政策。

我不会编写我自己的异常抛出代码,因为我没有直接处理那些可能出错的事情,因此抛出会很有用。如果出现严重错误的地方,没有明显的方法可以解决问题,那么投掷是一个好主意。

我确实试图确保我写的内容能够在抛出异常的情况下正常工作。

答案 4 :(得分:0)

根据我的经验,如果我使用异常来“巧妙地”恢复,那么随着时间的推移,异常处理往往会越来越复杂,因为它最终会增加与价值相比过多的开销。相反,我采用了纯粹用于检测的异常方法,在函数中抛出异常并在此时记录异常允许我更快地找到ev。问题。使用层次结构重新抛出异常以在更高级别捕获它我尝试了但发现它使代码不必要地难以遵循而没有主要好处。

答案 5 :(得分:0)

上次我使用它们:

抛出“常量(适当)错误消息”

遇到严重的情况时。

有几次我在全局变量中粘贴了额外的数据,但那是在我编写多线程代码之前。我必须重新考虑那个(显然)。

不是我再推荐这种技术了。