错误处理:在C ++中返回值与异常

时间:2010-06-24 21:41:25

标签: c++ oop exception-handling

在询问捕获'除以0'异常的过程中,我发现使用C ++,我们不能这样做。我的意思是,除以0不会抛出std :: exception。

我发现的一些提示是我必须检查值,并自行抛出异常。

我说这很令人困惑,因为我认为C ++采用了异常的想法,以便通过返回值方法替换“旧的C / UNIX报告错误”。

以下是我的问题

  • Q1:为什么C ++不会因为除以0而抛出std :: exception错误?这背后有什么理由吗?
  • Q2:通常,C ++用户使用什么错误处理方案?总是抛出错误,异常是除以0错误?
  • 问题3:一般来说,OOP语言更喜欢(甚至强制)使用异常。这是对的吗?

7 个答案:

答案 0 :(得分:9)

C ++假设您知道自己在做什么,不为您不需要的事情付费,也不会对其所针对的平台做出任何假设。

如果你想划分数字,那么要求编译器检查分母并在分割之前抛出是非常低效的。 (我们没有要求它这样做。)所以这个选项已经出来了;我们不能对每个部门进行检查,特别是浪费,因为大多数部门都不是零。

那么,我们怎样才能将零除以找出它是否有效?因为C ++不能假设它的平台,它不能假设有一种方法来检查结果,硬件方面。也就是说,虽然许多CPU会在分零时跳转到某种类型的中断,但C ++语言无法保证这样的事情。

唯一的选择是让行为不明确。而这正是你得到的:未定义的行为。


OOP语言可能会做某些事情或者其他事情,因为OOP没有明确定义而且C ++不是OOP语言也没关系。通常,使用最合适的工具。 (例外情况适用于特殊情况。)

答案 1 :(得分:2)

C ++在许多不同的平台上实现,旨在支持高性能应用程序。允许未定义的行为意味着不是所有的除法使用都需要通过额外的检查和编译器可能的异常抛出来加重。允许编译器实现机器码中除法的最快转换,无论其除以零的行为如何。

与执行任何操作一样,程序员有责任确保满足任何前提条件。在除法的情况下,程序员可能知道除数不能为零(或非常小)并且可能只使用断言;在其他情况下,如果不满足条件,他可能需要验证输入并抛出特定于应用程序的异常。

C ++不是(仅仅)OO语言,并且(在大多数情况下)不强制使用异常。它提供了它们作为适当使用的工具。还有其他语言可以在更大程度上强制使用例外。

答案 2 :(得分:2)

1)抛出异常是一项昂贵的操作。 C ++哲学不是要为你不使用的东西买单。如果你想要例外,你自己抛出它们(或者使用那些库)。

2)永远不要接受零除错误。这取决于具体情况,如果您知道输入将永远不会是0从不检查它。如果您不确定,请务必检查。然后要么抛出异常,要么静静地吞下错误。这取决于你。

3)异常抛出,特别是与RAII相结合,可以实现真正优雅和美观的代码。这在所有情况下都是不可接受的。您可能对您的输入有100%的信心,并希望获得原始性能。如果你正在创建一个DLL,你真的不想从你的api中抛出异常,但对于一个严格一致的静态链接库,你会被建议。

答案 3 :(得分:1)

除以零是你可以在计算线之前测试的东西,如果它是一个复杂的公式,可以避免浪费周期。

答案 4 :(得分:1)

C ++在某些地方没有使用很多好的原则来保持与C代码的兼容性。 Java等没有这样的限制,所以他们可以做他们想做的事。

在C ++中,总是抛出异常。但是,对于像零除零的东西,你真的应该自己检查一下。这不是一个特例,你没有检查自己。

答案 5 :(得分:1)

关于Q3 - 异常是应该发生的异常:) 所以要避免(div0可能)总是更好。 除了Emyr(谁正确地说“避免浪费计算周期”)你应该考虑抛出一个异常意味着很多“内部工作”,因为上下文改变了(你可以留下循环,函数,实例方法....)并且你的“激活堆栈”必须准备好。

因此,通常异常处理是处理异常的“常用方法”。但它不应该是避免“价值检查”的模式。

if(!string.IsNullOrEmpty(....)... 好多了 尝试{ XX = MyMabeNullString.Length ... } 抓住{ // errmess - 我之前可以检查一下:) }

答案 6 :(得分:1)

  1. 因为C ++旨在“接近金属”,并且大多试图将相对直接的简单操作(如除法)传递给硬件(因此,如果您不能依赖硬件来强制执行约束,那么C ++可能也不会默认)。
  2. 我认为没有一个普遍的答案。一些C ++程序员编写几乎类似于C的代码,几乎从不使用异常处理。其他人则非常严格地使用异常处理(大多数介于两者之间)。
  3. 虽然OO和异常处理之间几乎肯定存在相关性,但我认为这不是真正的因果关系。我认为可能的因素是:
    1. OOP和异常处理在类似(例如,大型)项目中最有用。
    2. 随着时间的推移,OOP和异常处理都变得越来越普遍。较旧的OO语言通常缺乏异常处理。较新的语言通常有异常处理,即使它们根本不是OO。