我有一个嵌套的try-catch代码,如下所示:
void A()
{
try
{
//Code like A = string(NULL) that throws an exception
}
catch(std::exception& ex)
{
cout<<"in A : " << ex.what();
throw ex;
}
}
void B()
{
try
{
A();
}
catch(std::exception& ex)
{
cout<<"in B : " << ex.what();
}
}
运行后我得到了这个结果:
in A: basic_string::_M_construct null not valid
in B: std::exception
正如您所看到的,ex.what()
在功能A中正常工作,并告诉我正确的说明,但在B ex.what()
只告诉我std::exception
。为什么会这样?
我在函数A的catch子句中抛出了不同或错误的东西吗?如何抛出嵌套异常以便我可以在B中获得确切的异常描述?
答案 0 :(得分:41)
将throw ex;
替换为throw;
。
执行后者将通过引用重新抛出异常ex
,,从而避免尝试制作价值副本时的危险:请参阅What is object slicing?
(请注意,即使您撰写ex
) 也允许修改 throw
。
答案 1 :(得分:32)
您在ex
中抛出了异常A
的副本。这会导致对象切片将具体异常转换为std::exception
。
要重新抛出您以多态方式捕获的实际异常,请使用throw;
语句。
值得记住斯科特迈耶斯在他的书中所说的话。你按值抛出,应该通过引用来捕获。
答案 2 :(得分:7)
您slicing原始异常对象,请尝试
try {
throw std::runtime_error("Hello world");
}
catch (std::exception& ex)
{
cout << "in A : " << ex.what();
throw; // Rethrows the original exception - no copy or slicing
^^^^^^
}