2013-07-01 102 views
15
A:  catch(...) 
B:  catch(std::exception& e) 

问题是A可以捕获但B不能。std :: exception和“...”之间的区别

为什么在C++中通用的根异常,可以捕捉到任何没有出台

---附加 我很抱歉,我应该说我用C明白++,你可以抛出任何类型如int,但除此之外,还有什么可以抛出的?

我的问题是,我试图找到什么异常是从代码引发的,它可以被A但不是B捕获。这个异常绝对不是像“int”这样的类型。它必须是系统异常或内存违规类的事情。我只是想知道那可能是什么。

+0

C++没有 '根' 的异常类型所有异常继承,因为C++可以抛出任何东西,包括不能继承的类型;例如'int'。 C++可以抛出任何东西,因为他们没有看到让异常变得不那么普遍的理由。它类似于C++模板; C++模板不依赖于继承,因此比一般依赖继承的Java或C#泛型更通用。 – bames53

+1

某些Windows SEH异常有时可能被'...'发现,但不会被'std :: exception'发现。只有当你疯狂的标志编译,使用推荐/ EHSC(如果可以的话),你会被罚款 –

+0

@MooingDuck –

回答

28

catch (...)是一个所谓的“catch all”块。它会捕获任何 C++异常。

catch(std::exception& e)将捕获只有std::exception派生的例外。

这里是一个将被捕获所有被称为一个例外的例子,但不是第二个版本:

throw 42; 

这听起来很奇怪,你,它是。要认识到的重要一点是,任何东西都可以作为C++异常抛出 - 不仅仅是exception或从exception派生的东西。正如@ bames53在注释中提到的那样,没有任何异常类型来源于所有异常,就像其他语言一样。

重要的是要注意,一个全通块很容易被滥用。事实上,作为一般的经验法则,最好假设所有全部封锁都是程序缺陷。当然,编程中并没有“永远”,但是当你学习使用异常时,这是一个安全的假设。

为什么catch-all模块是邪恶的原因是因为它们通常如何使用。通常情况下,一个天真的程序员会编写一个捕获所有程序来试图捕捉任何编程错误,然后批判地继续让程序运行,就好像什么也没发生一样。这是一场等待发生的灾难。程序状态现在是不确定的。某个地方出了问题。你不能安全地忽略异常,并继续像一切都很好。即使你的程序继续运行,可能会在某处发生微妙的堆损坏,会掺杂程序的计算或其输出。发生堆损坏时,作为程序员可以希望的最好的事情是立即崩溃。这样你就可以在腐败点得到一个调用堆栈和一个转储文件,并找到并解决问题。但是,当你有一个全面的地方,你已经失去了腐败发生的所有背景。在你的代码中找到真正的缺陷几乎是不可能的。


当然,捕获所有处理程序是有效的和有价值的用法。最常见的一种情况是编写一个全局异常处理程序,然后重新编号为throw。这个全局处理程序可以启动某种故障记录,可能是通过记录错误本身,或者产生一个外部程序来记录失败程序以外的记录。通过重新抛出异常,您可以为委托人提供处理可以处理的异常的机会,同时允许无法处理的异常终止程序。

重新执行异常很简单。只需拨打throw不带参数,如:

catch (...) 
{ 
    // some magic 
    throw; 
} 

另一件事要记住的是,当你做捕获一个例外,它通常最好赶const参考,而不是只是一个参考。

+5

此外,一些老版本VC++的(甚至有某些设置更新)也陷入异常SEH用' catch(...)',这绝对不是一个好主意(你可能最终会忽略访问冲突或用于扩展堆栈的页面防护例外)。 –

+0

@MatteoItalia:你确定吗?我已经和SEH打交道已经很长时间了,你可能是对的,但我不记得。 –

+0

我不确定旧的默认行为,但您仍然可以更改设置以启用捕获SEH异常。 – jerry

1

int s怎么样?

try { 
    throw 123; 
} catch (std::exception &e) { 
    // this won't catch 
} catch (...) { 
    // this will catch 
} 
2

简短的答案是什么,没有它的(公共)继承层次结构std::exception

#include <exception> 
#include <iostream> 

int main() 
{ 
    try 
    { 
     throw false; 
    } 
    catch(std::exception& e) 
    { 
     std::cout << "Caught std::exception" << std::endl; 
    } 
    catch(...) 
    { 
     std::cout << "Caught something else" << std::endl; 
    } 

    return 0; 
} 

输出:

Caught something else
相关问题