何时捕获异常?

6

如果我不使用异常,以下操作会有什么区别吗?

void func()
{
    try
    {
        if (n > 5)
        {
            throw "n is greater than 5";
        }
    }
    catch (const char *e)
    {
        MessageBox(0, e, 0, 0);
        return;
    }
}

或者

void func()
{
    if (n > 5)
    {
       MessageBox(0, "n is greater than 5", "Error", 0);
       return;
    }
}

1
在第一种情况下,如果你把 char const* 扔进去,你会被批评的。 - Matthieu M.
可能在标题“错误”和反向工程代码时会有所不同. . . - k06a
9个回答

8
我会建议你不要将异常用于流程控制。异常,正如其名称所示,是用于处理特殊情况的。在上述情况中,您明显希望n可能大于5,因此这并不是一个特殊情况。如果应用程序有办法处理该情况,则应优先处理,而不是引发异常。
我相信有些情况下这种逻辑会失败,但总体而言,我认为这是个好的经验法则。
但从技术角度来说,两者之间没有太大区别(如果你经常这样做可能会影响性能)。

3

不要在同一个函数中抛出并捕获异常,这表明你正在使用异常来进行标准的控制流程,而这最好使用if/while/break等语句完成。


@Alf:通常你不应该说永远不会。但这是唯一的例外! :) - Ned Batchelder
好的,那么,在同一个基于异常的函数中抛出和捕获异常的规则的例外情况之一是,在C++中模拟类似Java异常的“finally”。虽然RAII通常会更加清晰,但我猜想可能会有一些例外情况?干杯! - Cheers and hth. - Alf

2

最终结果肯定是一模一样的。

在代码中应尽可能简化事物,因此我强烈反对在这种情况下使用异常。


2

很难确定何时应该使用异常。在某些情况下,异常是明显的赢家,而在其他情况下则不是。

问题的核心在于n从哪里来,它在正常情况下是否可以是一个大于5的值。如果n由函数本身计算并且通常可以具有此值,则不应该抛出异常。如果n是在其他地方指定的,并且该函数不希望出现高值,则抛出异常更为合适。

然而,在你的示例中,我会说这是异常的不良使用。在同一函数内抛出和捕获异常几乎总是不好的形式。这是标准的流程控制。只有当错误条件需要传播到函数外部时,才应该使用异常。


0
void func()
{
    if (n > 5)
    {
       MessageBox(0, "n is greater than 5", "Error", 0);
       return;
    }
}

如果你可以通过像上面的代码一样进行检查来处理异常,就不要自己抛出异常,这不是一个好的做法。


0

您没有定义n

使用以下n的定义,会有不同的可观察行为:

struct Silly
{
    ~Silly() { cout << "Hm de dum" << endl; }
    operator bool() const { return true; }
};

struct SillyProducer
{
    Silly operator>( int ) const { return Silly(); }
};

#define n   Silly silly = SillyProducer()

祝好,希望对你有所帮助。


0

已经有很多话题被讨论过了,我只想从我的角度添加一些内容。

在你的情况下,两种情况都是正确的,但我鼓励将其分为两个层次:逻辑和视图。所以你的逻辑层应该做:

    doLogic()
    {
      if (n > 5)
      {
         throw "n is greater than 5";
      }
      ///Something more
    }

而你的视图层可能会执行:

try
{ 
   doLogic()
}
catch (const char *e)
{
    MessageBox(0, e, 0, 0);
    return;
}

但是,正如其他人所说:最重要的是n从哪里来。如果您期望它大于5,则只需使用if() else,而不是异常。但是,如果n总是小于5,并且如果大于5表示您的系统出现了问题,则请使用异常。


0

在您的示例中,实际上没有什么区别(除了一个使用异常,另一个不使用!)- 这将是一个合理的重构。但是,如果有很多不同的错误条件,您可能会发现throw...catch模式可以帮助您将错误处理集中在一个地方。


0
在你的例子中,没有区别。唯一需要弄清楚的是,当抛出异常时,try...catch方法中找到的其余语句将永远不会被执行。 异常基本上用于处理“改变程序执行正常流程的特殊条件”。(你的只是基本的逻辑错误流程)。
希望这可以帮助你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接