C++ 为什么要尝试…catch需要抛出确切的类型
我可以做到,没问题:C++ 为什么要尝试…catch需要抛出确切的类型,c++,exception-handling,C++,Exception Handling,我可以做到,没问题: long lngval = 3L; int i = lngval; 但如果我尝试这样做: try { throw 3L; } catch(int i) { cout << "caught " << i << endl; } 试试看{ 投掷3L; } 捕获(int i){ cout您可以在一个try-catch块中捕获多个类型。为了让编译器知道要抛出到哪个catch块,它必须能够匹配确切的类型。或者它可以有一个默认的catch
long lngval = 3L;
int i = lngval;
但如果我尝试这样做:
try {
throw 3L;
}
catch(int i) {
cout << "caught " << i << endl;
}
试试看{
投掷3L;
}
捕获(int i){
cout您可以在一个try-catch块中捕获多个类型。为了让编译器知道要抛出到哪个catch块,它必须能够匹配确切的类型。或者它可以有一个默认的catch块--catch(…){}
,但是您将无法获得在这种情况下抛出的值。catch语句捕获一个对象(在您的例子中是标量变量)给定其类型,因此如果类型不匹配,它将传递到下一个catch语句(如果有)或默认异常接收器
在您的例子中,您可以让第二个catch语句捕捉长的内容,或者在其他地方,这样您的catch语句就不会捕捉任何内容
要捕获任何异常,只需使用catch(){}:)
一个提示,最好使用异常类,或者根据自己的需要将其子类化:)在第一种情况下,编译器可以准确地告诉您要做什么:将长的转换为int
。在第二种情况下,编译器必须假设您可能有这样的构造:
try {
try {
throw 3L;
}
catch (int i) { /* P */ }
}
catch (long l) { /* Q */ }
其思想是,编译器永远无法知道是否有catch(long l)
潜伏在当前上下文之外,因此只选择第一个可能的转换是不安全的
这也是为什么在抛出异常时通常使用类层次结构,而不是像int
或long
这样的随机类型:这样可以很容易地向异常处理程序添加或多或少的规范,编译器可以确定您的意图(通过关系).您也可以抛出3;
-没问题
int
和long
是不同的类型。异常处理的一个优点是,您可以通过查看其类型来区分异常(一个中央try块可以处理来自不同位置的各种异常/try块可以处理某些类型的异常,让其他异常传播)
此外,建议抛出一个标准异常或从其中一个异常派生一个类。如果您只想处理异常,而不关心特定类型,则可以使用catch(const std::exception&)
。catch
不一定需要确切的类型
使用从std::exception
(可在
中找到)派生的异常是一种常见且良好的做法。原因是您可以通过多态方式捕获异常,也就是说,您不需要知道确切的类型(另请参见),并且我们有一个处理该异常的约定
您可以使用标准提供的一种方法(例如,std::range\u error
),或者如果没有任何方法可以解决您的问题,请专门化std::exception
:
#include <stdexcept>
class moores_law_stopped : public std::exception {
public:
virtual ~moores_law_stopped() throw() {}
virtual const char *what() const throw() {
return "moores law stopped. duck under your table.";
}
};
#include <iostream>
int main () {
try {
throw moores_law_stopped();
} catch (std::exception const &e) {
std::cerr << "oh oh: " << e.what() << std::endl;
}
}
约定是通过引用捕获或const引用,这样您就可以毫无恐惧地获得多态行为。写100遍:“我将只抛出从std::exception派生的对象”@Tadeusz,除了抛出一个int
终止程序的常见习惯用法。(main
包含一个try…catch
来捕获int
并返回它。这个习惯用法与调用exit
的效果相同,只是调用了所有局部变量的析构函数。)@JamesKanze:有趣的是,我不知道这个成语。我确实看到了一个从无到有的自杀例外,有一次,我想你会猜到这个角色。在这两种情况下,尽管你真的认为没有人写过一个捕获(…)
clause.@JamesKanze:我听说过这个习惯用法,但我认为它并不常见。如果你想半立即退出,那会是什么情况?如果你不能处理异常,就不要抓住它。如果你能抓住它,那么就抓住它。@phresnel我不知道这个习惯用法有多普遍,尽管我自己经常使用它。这是一个有效的例子,如果你不能处理异常,就不要抓住它我抛出了一个int
(说实话,这是我能想到的唯一一个。)
oh oh: moores law stopped. duck under your table.