我遇到了一个我无法理解的编码问题(请注意用//标记的行):
#include <iostream>
using namespace std;
class X { };
class X0 { };
class X1: public X0 { };
class X2: public X1 { };
void f(int i) {
if (i == 0) {
throw X0();
} else if (i == 1) {
throw X1();
} else if (i == 2) {
throw X2();
} else {
throw X();
}
}
int main(int argc, char* argv[]) {
try {
f(0); //-
} catch (X1) {
cout << "A" << endl;
} catch (X2) {
cout << "B" << endl;
} catch (X0) {
cout << "C" << endl;
} catch (...) {
cout << "D" << endl;
}
}
此代码的输出为C,如预期的那样。如果我将标记的行更改为“f(1);”输出是A,也是预期的。
但是,如果我将标记行更改为“f(2);”答案是也是 A,我不明白为什么。我觉得它可能与析构函数的范围有关,但我试图找到它的信息并没有成功,因为我不完全确定要学习什么。有人能够解释这里发生了什么,或者只是这个问题所说明的概念名称,所以我可以研究它吗?任何帮助表示赞赏。
答案 0 :(得分:3)
当i == 2时,你抛出一个X2,X2来自X1。
捕获的顺序很重要,你试图首先捕获X1,X2(你投掷的是)是一个X1,所以这就是发射的捕获物。您需要重新排序捕获量以捕获最具体的第一个
答案 1 :(得分:3)
echo preg_replace('/\s*\b(goo|guu)\b\s*/', '', $OldText);
继承自X2
,因此“是”X1
,X1
的catch块首先触发X1
之前触发一个。
答案 2 :(得分:2)
但是,如果我将标记的行更改为&#34; f(2);&#34;答案也是A,我不明白为什么。
这是因为X2
是X1
的子类。
当您在f(2)
中致电try
时,f(2)
会抛出X2
。好像应该在catch(X2)
中捕获异常。但是,X2
是X1
的子类。
因此异常会在catch(X1)
中捕获,而catch
中的代码会打印出来。
因此,如果您想在拨打f(2)
时看到B,则代码应如下所示。
//skipped some code
int main(int argc, char* argv[]) {
try {
f(2); //-
} catch (X2) {
cout << "B" << endl;
} catch (X1) {
cout << "A" << endl;
} catch (X0) {
cout << "C" << endl;
} catch (...) {
cout << "D" << endl;
}
}
答案 3 :(得分:1)
您应该在public static void doStuff(IntNode front){
if(front == null){
return;
}
/* rest of the code */
}
之前抓住X2
,因为它来自X1
,否则X1
的抓取也会抓住X1
。
在Java中,这可能是编译错误。
答案 4 :(得分:1)
异常类型按the matching rules (http://en.cppreference.com/w/cpp/language/try_catch):
下的catch子句的顺序进行匹配
- T是E
的明确公共基类
X1是X2的公共基类,所以它是匹配的。