【问题标题】:ex.what() changes in nested try-catchex.what() 嵌套 try-catch 的变化
【发布时间】:2017-04-22 09:32:05
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

throw ex; 替换为throw;

执行后者将重新抛出异常ex通过引用,因此避免了尝试进行值复制的危险:请参阅What is object slicing?

(请注意,您允许修改ex,即使您写throw)。

【讨论】:

  • 关于@StoryTeller 的回答,我接受你的回答,因为有额外的链接和你最后的观点。
  • Nitpick,但我认为您的意思是 throw;,因为 (AFAIK) throw 本身是无效的。
【解决方案2】:

您在A 中抛出异常ex 的副本。这会导致对象切片将具体异常转换为std::exception

要重新抛出您以多态方式捕获的实际异常,请使用throw; 语句。

值得牢记 Scott Meyers 在他的书中所说的话。你按值抛出,应该按引用捕获。

【讨论】:

    【解决方案3】:

    你是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
      ^^^^^^
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2023-03-19
      • 2017-09-30
      相关资源
      最近更新 更多