嵌套try-catch中的ex.what()更改

时间:2016-12-07 12:26:13

标签: c++ exception-handling try-catch

我有一个嵌套的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中获得确切的异常描述?

3 个答案:

答案 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
  ^^^^^^
}