A: catch(...)
B: catch(std::exception& e)
Run Code Online (Sandbox Code Playgroud)
问题是什么可以A捕获但B不能.
为什么在C++中没有引入可以捕获任何内容的通用根异常
---添加我很抱歉,我应该说我在C++中理解你可以抛出任何类型的int,但除此之外,还有什么可以抛出?
我的问题是我试图找到从代码抛出的异常,它可以被A但不是B捕获.这个异常绝对不是像"int"这样的类型.它必须是系统异常或内存违规.我只是想知道那可能是什么.
Joh*_*ing 29
catch (...)是一个所谓的"全部捕获"块.它将捕获任何 C++异常.
catch(std::exception& e)将只捕获派生自的异常std::exception.
以下是catch-all调用的异常示例,但不是第二个版本:
throw 42;
Run Code Online (Sandbox Code Playgroud)
这对你来说可能有些奇怪,而且确实如此.要意识到的重要一点是,任何东西都可以作为C++异常抛出 - 而不仅仅是exceptions或派生自的东西exception.正如@ bames53在评论中提到的那样,没有根异常类型可以派生所有异常,就像在其他一些语言中一样.
同样重要的是要注意,一个包罗万象的块很容易被滥用.事实上,作为一般的经验法则,最好假设所有的catch-all块都是程序缺陷.当然,编程中没有"总是",但是当你学习使用异常时,这是一个安全的假设.
catch-all块是Evil的原因在于它们通常如何使用.通常,一个天真的程序员会编写一个catch-all来尝试捕获任何编程错误,然后,批判性地,继续让程序运行,好像什么也没发生.这是一场等待发生的灾难.程序状态现在是不确定的.某事,某个地方出了问题.你无法安全地忽略异常并继续前进,就像一切都很好.即使您的程序确实继续运行,也可能存在某个细微的堆损坏,这会破坏程序的计算或输出.当堆损坏确实发生时,你作为程序员所希望的最好的事情是立即崩溃.这样,您可以在损坏点获取调用堆栈和转储文件,并找到并修复问题.但是当你有一个全面的时候,你已经失去了发生这种腐败的所有背景.几乎不可能在代码中找到真正的缺陷.
当然,catch all处理程序的有效和有价值的用途.最常见的一种是编写一个全局异常处理程序,然后处理throw异常.这个全局处理程序可以启动某种故障记录,可能是通过记录错误本身,或者产生一个外部程序来执行故障程序之外的日志记录.通过重新抛出异常,您可以为代理提供处理可以处理的异常的机会,同时允许无法处理的异常终止程序.
重新抛出异常很容易.只需throw不带参数调用,如:
catch (...)
{
// some magic
throw;
}
Run Code Online (Sandbox Code Playgroud)
要记住的另一件事是,当您捕获异常时,通常最好捕获const引用,而不仅仅是引用.
| 归档时间: |
|
| 查看次数: |
2513 次 |
| 最近记录: |