想象两段相似的代码:
try {
[...]
} catch (myErr &err) {
err.append("More info added to error...");
throw err;
}
和
try {
[...]
} catch (myErr &err) {
err.append("More info added to error...");
throw;
}
这些实际上是相同的,还是在某些微妙的方面有所不同?例如,第一个是否会导致运行复制构造函数,而第二个可能会重用相同的对象来重新抛出它?
最佳答案
根据您如何安排异常层次结构,通过在 throw 语句中命名异常变量来重新抛出异常可能切片原始异常对象。
无参数 throw 表达式将抛出当前异常对象并保留其动态类型,而带参数的 throw 表达式将根据 static 参数的类型向 抛出
。
例如
int main()
{
try
{
try
{
throw Derived();
}
catch (Base& b)
{
std::cout << "Caught a reference to base\n";
b.print(std::cout);
throw b;
}
}
catch (Base& b)
{
std::cout << "Caught a reference to base\n";
b.print(std::cout);
}
return 0;
}
如上所写,程序会输出:
Caught a reference to base Derived Caught a reference to base Base
如果 throw b
被替换为 throw
,那么外部 catch 也会捕获最初抛出的 Derived
异常。如果内部类通过值而不是通过引用捕获 Base
异常,这仍然成立 - 尽管这自然意味着原始异常对象无法修改,因此对 b
的任何更改> 不会反射(reflect)在外部 block 捕获的 Derived
异常中。
关于c++ - throw 和 throw 与捕获异常的 arg 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1481612/