如何在C++中捕获'any'异常?

How to catch 'any' exception in C++?

本文关键字:异常 any C++      更新时间:2023-10-16

我的理解是,c++中的所有异常最终都扩展了exception。在Java世界中,无论异常的类型如何,捕获Exception e都会起作用。这是如何在C++中完成的?

为什么这个片段中的异常没有被捕获?

try{        
    int z = 34/0;
    cout << "This line should not appear" << endl;
} catch (exception e) {
    cout << "An error has occurred: " << e.what();  // Not executed
}

此外,在C++中,如何找出哪些操作导致了什么异常?

为什么在这个片段中没有捕捉到异常

整数除以0不是标准的c++例外。因此,在这种情况下不会抛出异常,您得到的是一个简单的未定义的行为

某些特定的编译器可能会将此场景映射到特定的异常,您必须检查编译器文档才能找到相同的异常。然而,使用这样的功能将是不可移植的,并且您的代码将仅限于您的特定编译器。

在这种情况下,最好自己检查错误条件(除数等于零),然后显式抛出异常。

此外,在C++中,如何找出哪些操作导致了什么异常

std::exception类专门为此提供了一个方法std::exception::what()

除以0会导致大多数CPU遵循某种升级过程,在CPU制造商的行话中,这种过程可能被称为异常、信号、中断、陷阱或其他什么。这些都与C++语言异常没有任何直接关系,即使也使用了"异常"一词。

在C++中,由于重复测试除以零的CPU周期和目标代码大小通常很昂贵,因此编译器为内置类型生成的代码不需要进行任何此类检查。在实践中,通常只要相信程序员会编写代码来避免被零除,在有用的除法子集中插入显式检查就足够了;考虑这样的检查以避免冗余。

如果程序员想要一个一致的有保证的检查,他们可以创建一个用户定义类型(一个带有自定义重载运算符的类),该类型可以用来代替内置的数字类型,但需要花时间检查是否被零除(或下溢、溢出或开发人员关心的任何其他问题),并根据程序员的喜好做出反应。我发现像JAVA和C#这样的语言缺乏运算符重载,我想这意味着它们不能以这种方式轻松地替换内置类型,需要侵入性的代码更改来显式调用函数,而不是使用直观的数学运算符。

无论如何,由于C++标准本身并没有为除以零的情况指定一些行为,因此如果实现愿意,它可以自由地提供一些潜在有用的行为。这可能包括以某种方式生成一个实际的C++语言异常,但在实践中,它可能在CPU周期和代码大小方面过于昂贵,无法证明其合理性。也许JAVA是如此缓慢和臃肿,以至于像这样的额外检查既不在这里也不在那里…?;-)

假设您使用的是x86系列CPU,则0除通知的术语是"中断"。但是,如果该机器运行的是UNIX或Linux,那么划分会在操作系统级别产生一个"信号",您可以设置一个信号处理程序来获得问题通知。

您编写

我的理解是,c++中的所有异常最终都扩展了exception

这是错误的。C++异常可以是大多数任何类型的异常。在C++98中,它必须是可复制的,但很可能(也是最有可能)C++11取消了这一限制。

在Java世界中,无论异常的类型如何,捕捉异常e都会起作用。这是如何在C++中完成的?

通过一个包罗万象的条款,

 nbsp nbsp;catch( ... )

这方面的主要问题是,如果您想要有关异常的任何信息,那么在C++98中,您必须重新抛出,这不是一种特别有效的方法。和C++11&rsquo的;截至2012年,您的工具链可能还不支持的异常处理功能。

为什么这个片段中的异常没有被捕获?

因为没有C++例外。通常,编译器会简单地拒绝编译常量表达式34/0。除了g++之外,我想不出任何编译器会编译它:你真的编译过那个代码吗

无论如何,如果一个人成功地编译了该代码,那么从标准C++的角度来看,它只会导致未定义的行为,在那里什么都不可能发生。如果您;你很幸运;我会得到signal,但什么都没有;s保证。然而,可以使用特定于平台的功能来捕捉此类事件。

在C++中被零除不会引发异常。例如,请参见此处、此处和此处。