为什么必须声明例外?

时间:2015-04-09 02:27:20

标签: c++ exception-handling

可以认识到,在C ++中,如果方法抛出异常,则必须声明它。 但是,为什么这种规则必须适用的令人信服的理由似乎对一些人来说不太了解(我问了一些同事,没有令人信服的答案)。

有人可以向我解释,也许是从编译器方面解释为什么我们绝对需要在抛出它的方法中声明异常?谢谢。

2 个答案:

答案 0 :(得分:2)

正如评论者已经说过的那样,需要在函数上放置异常规范(通过throw(),这在C ++ 11中已弃用)。这是Java的要求(即检查异常,因为它们被称为)。

但是,你在C ++ 11中可以做的是将标记函数标记为noexcept,这意味着它们不会抛出。这为编译器提供了一些自由来优化一些它本来无法实现的功能,因为它不知道函数是否可以抛出。在函数上使用noexcept规范的后果是,如果它们以某种方式抛出,将调用std::terminate,从而有效地“崩溃”您的应用程序。希望这会有所帮助。

答案 1 :(得分:1)

不推荐使用异常规范的一个原因如下。请考虑以下代码:

#include <iostream>

void h() // no exception specification
{
    throw double(0); // throws double
}

void f() throw(int)
{
    h(); // suppose we were sure that h() doesn't throw
}

int main()
{
    try
    {
        f();
    }
    catch (int)
    {
        std::cout << "int exception caught" << std::endl;
    }
    catch (...)
    {
        std::cout << "Other exception caught" << std::endl;
    }
}

假设我们认为f()仅抛出int,因此我们通过异常规范指定它。但是,f()使用了一些我们无法控制的第三方库函数h()(这里我们定义了它,但在实际代码中,您可以假设h()是通过共享库调用)。现在,在版本中。 0.1,我们知道h()没有投掷(或者只投掷int),因此我们可以在f()的代码中安全地使用它。但是,图书馆开发人员认为在某些情况下抛出double是个好主意,所以他们修改了h()现在抛出double(我们盲目地升级了我们的图书馆所以现在我们有了#34;新&#34; h()

现在你看到会发生什么:h()double内投掷f()。但是,f()被标记为throw(int),因此所有投注都已关闭,程序最终会调用terminate,bam。

请注意,通过不指定throw(int),我们可以通过最后double块捕获catch(...)异常。

这只是考虑例外规范的原因之一&#34;不良做法&#34;并且由于这种代码破坏而被弃用了。还有更人为的例子,搜索你最喜欢的搜索引擎会发现一些非常好的答案。