what()不抛出(异常类)是否重要?

时间:2016-01-14 21:55:23

标签: c++ c++11 exception throw

来自C ++ Primer的练习提出

  

为什么[异常类]的函数不会抛出是很重要的?

由于无法检查我的答案,我希望得到一个意见。我认为可能是一个错误(可能terminate将被调用)在catch子句(除了重新抛出throw;)期间抛出另一个异常,而当前的异常对象仍在处理。看起来情况并非如此,抛出catch子句是完全可以的:

#include <iostream>

using namespace std;

int main(){


    try{
        try{
            throw exception();
        } catch(exception err){ throw exception();}
    } catch(exception err){ cout << "caught"} //compiles and runs fine, outputs "caught"


}

所以程序终止不用担心。那么,如果()投掷应该产生的任何问题,至少应该由用户纠正,如果他们如此倾向。

也许那时,重要性可能是在处理错误时我们不希望发生进一步的意外错误? catch子句内部的抛出主要用于在调用链的上游发送异常对象。用户可能从他的程序深处收到错误,并且不想担心捕获的错误必须与其自己的try块相关联。或者也许what()有自己的抛出也可能导致递归效果(例如what()抛出异常,然后我们捕获这个异常并调用what()但是然后抛出,依此类推)意味着它可能变得无法处理有什么错误?什么()可能会抛出多么激烈?

3 个答案:

答案 0 :(得分:3)

我认为没有什么不清楚 - 就像你描述的那样。如果异常类的.what()方法引发错误,则整个 catch工作浪费了

try {
  someDangerousOperation();
}
catch(std::exception e) {
  // Ooops, instead of false,
  //we get another exception totally unrelated to original error
  someLogClassOrWhatever.save(e.what());
  return false;
}
return true;

如果您需要处理what()的例外情况,请想象一下疯狂的代码:

try {
  someDangerousOperation();
}
catch(std::exception e) {
  // Not very fun
  try {
    someLogClassOrWhatever.save(e.what());
  }
  catch(...) {
    alsoWhatHasFailedThatIsReallyGreat(); 
  }
  return false;
}

我认为没有更多内容,可能问题很简单,似乎必须有一些隐藏在其中的问题。我认为情况并非如此。

答案 1 :(得分:2)

std::exception::what()是noexcept。因此,如果它抛出,则调用std::terminate。是的,这很重要。

答案 2 :(得分:1)

想象一个非常好奇的编码器,有一种轻微倾向于成为控制狂(我自己也知道其中几个),他真的想知道他的程序出了什么问题并用ex.what()记录所有错误。所以他编码

try {
  code();
}
catch(std::exception &e) {
  std::cout<<e.what()
}

他对整个世界非常满意,特别是对自己。但现在它已经超越了他的想法,e.what()也可以抛出异常。所以他是代码:

try{
    try {
      code();
    }
    catch(std::exception &e) {
      std::cout<<e.what()
    }
}   
catch(std::exception &e) {
      std::cout<<e.what()
}

一分钟后,他注意到,还有一个未被捕获的异常可能!记住,他是一个控制狂,所以他打算写另一个try-catch块而不是另一个和另一个

所以你可以赌任何钱,他的项目会迟到 - 你怎么能这样对我的朋友这样做?所以请确保e.what()不抛出:)

我猜这是what无法接受的原因。