c ++尝试捕获实践

时间:2010-06-03 14:52:36

标签: c++ exception-handling

这在C ++中被认为是不错的编程实践:

try {
// some code

}
catch(someException) {
// do something
}
catch (...) 
{

// left empty   <-- Good Practice???
} 

10 个答案:

答案 0 :(得分:44)

没有!这是一种可怕的做法!

几乎只有catch (...)而不是重新抛出异常的时间才会在main()中捕获任何其他未处理的异常,并在退出之前显示或记录错误。

如果你catch (...),你完全不知道抛出了什么异常,因此你无法知道继续运行是否安全。

答案 1 :(得分:10)

良好的做法就是:

try {
// some code

}
catch( const someException & e) {
// do something
}

因为您知道要捕获的异常。

catch(...)应该只在你的main()和线程的入口点(没有异常应该离开线程),当然是一个catch(const std :: exception&amp; e)。

答案 2 :(得分:7)

这取决于您的应用程序和您尝试解决的问题。但总的来说,吞下未知的异常并不是一个好主意。至少,我会记录一些东西。

编辑:正如Noah Roberts所指出的那样,唯一一次这可能是一个合理的想法就是在析构函数中。在析构函数中禁止异常非常重要,否则可能会激活多个异常。例如,如果抛出异常,并且由于堆栈展开,会调用一些析构函数,这可能会发生。如果析构函数抛出异常,则会激活2个异常。然后C ++将调用std :: terminate(),默认情况下将结束你的程序。您可以为此条件安装处理程序,但除了记录正在发生的事情之外,您可能做的事情并不多。

尽管如此,即使在析构函数中,您也应该在catch (...)内记录一些内容。但是,根据它的析构函数,您可能没有可用的日志记录工具。但在大多数情况下,您仍然可以使用std::cerr

答案 3 :(得分:7)

没有。这不是C ++或任何其他语言的良好编程习惯。

无声的失败很糟糕,迟早会咬你的。

如果你要catch (...) 至少,你应该做的就是记录你正在做的事情。如果您不使用RAII,则可能还需要delete一些对象。

答案 4 :(得分:4)

我唯一能想到这可能是必要的 - 虽然这并不意味着它是好的 - 是在析构函数中。析构函数不能抛出,或者你会遇到比那些异常更糟糕的问题(可能没有bad_alloc)。如果什么东西你什么也没做的话什么东西扔了,那么你的捕获将是空的。你不能重新抛出,因为你在析构函数中......在这种情况下,你真的可以做到。

尽管如此,仍然需要在那里或其他地方断言。

当然,其他人提到过线程。我根本不做MT所以我不知道那里的问题。

答案 5 :(得分:4)

吃异常是一个坏主意。

至少,为您的例外实施某种日志记录。您可能需要考虑使用更好地描述问题的错误消息重新抛出异常。

答案 6 :(得分:2)

这是“依赖”问题之一。如果你正在处理一个记录不完整的第三方库,它继续并定义了自己的异常,它们没有从std :: exception继承,你可能没有任何其他选择。然后,我只会将其保留在我的代码的调试部分中。

答案 7 :(得分:2)

作为一种标准做法,这是一个非常糟糕的主意。如果您在不知道如何处理异常时开始吞咽异常,那么您就是一个。防止它们在调用堆栈中的更合适的位置处理,并且b。给你的程序一个继续处于某种错误状态的机会。

然而,也就是说,作为一名程序员,你有可能做出正确和合乎逻辑的决定,认为这是一个适当的时间来吞下一个例外。这可能需要执行后续步骤,例如执行清理并通知用户他们启动的操作失败。

底线,如果你无法确定捕捉的后果 - 不要抓住。

答案 8 :(得分:0)

实际上它实际上取决于你的整个程序打算做什么但是大部分时间吞下异常并继续执行并不是一个非常好的想法,好像什么也没发生,你需要知道代码实际上有什么问题,其中它坠毁等...

BaşakBilgi

答案 9 :(得分:0)

永远不要说绝对话。 我会说你几乎不应该吞下一个例外。但是,这是我的代码中的一个地方,我没有真正打扰过我:

class _ACLASS dstream 
    : public ofstream
{
//...
    long GetSize (void);
//...
Protected:
    string CheckRotation(void);
//...
};

string dstream::CheckRotation(void)
{   
//...
        // rotate if they aren't the same (it's a new day)
        // or our current file size exceeds the limit.
        if (currDay != newDay || GetSize() > fileSizeLimit * ONE_MEGABYTE)
        {
//...             
            Purge(); // while all files are closed, look for purge opportunity
            clear();
            open(Destination);
//...
}

// Return current file size
long dstream::GetSize (void)
{
    long retval =0;
    try {  // PBI 1227 was caused by this not being trapped.
        retval = (long)tellp ();
    } catch (...) { 
        retval =0; 
    } // Swallow the exception if any

    return retval;
}

这里我只想确定我的日志文件是否超过1 M字节(或者fileSizeLimit允许多个M字节),如果是,则旋转日志。如果我在这里得到一个例外,我将向调用者报告一个0字节大小,并且调用者此时不会选择旋转日志。在下次通话时,它可能会得到正确的答案并将其传递出来。

我想如果tellp()每次调用都会抛出一个异常,我的日志就不会旋转到午夜。但我怀疑这种情况会发生(而且我从未在现场看过它)