我需要在catch块中执行一些操作,然后抛出与我得到的相同的异常:
#include <string>
#include <iostream>
class AbstractError {
public:
virtual std::string toString() const = 0;
};
class SomeConcreteError : public AbstractError { public:
std::string toString() const { return "division bt 0"; }
};
class SomeOtherError : public AbstractError { public:
std::string toString() const { return "null pointer deref"; }
};
void foo(int i)
{
if (i > 2) { throw SomeConcreteError(); }
else { throw SomeOtherError(); }
}
int main(int argc, char **argv)
{
try { foo(argc); }
catch (const AbstractError &e)
{
std::cout << e.toString() << "n"; // do some action then re-throw
throw e; // doesn't work ...
}
return 0;
}
下面是我得到的错误:
main.cpp:28:15: error: expression of abstract class type ‘AbstractError’ cannot be used in throw-expression
28 | throw e;
| ^
这将抛出e
:
throw e;
但它是抽象的,所以不能这样做。您需要重新抛出相同的异常:
throw;
您已经尝试了throw
关键字的两种形式之一,您想要另一种:
catch (const AbstractError &e)
{
std::cout << e.toString() << "n"; // do some action then re-throw
throw;
}
描述很清楚:
- 重新抛出当前处理的异常。放弃当前catch块的执行,并将控制传递给下一个匹配的异常处理程序(但不传递给同一个try块之后的另一个catch子句:它的复合语句被认为已经退出),重用现有的异常对象:不创建新对象。
或者from [expr.throw]/3:
没有操作数的throw表达式会重新抛出当前处理的异常。用现有的异常对象重新激活异常;没有创建新的异常对象。该异常不再被认为是被捕获的。
作为旁白,是否有一个特殊的原因,你调用你的方法toString()
而不是std::exception
层次结构中使用的what()
?