来自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()但是然后抛出,依此类推)意味着它可能变得无法处理有什么错误?什么()可能会抛出多么激烈?
答案 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
无法接受的原因。