如何从catch块中重新抛出抽象类错误



我需要在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;
    }

描述很清楚:

  1. 重新抛出当前处理的异常。放弃当前catch块的执行,并将控制传递给下一个匹配的异常处理程序(但不传递给同一个try块之后的另一个catch子句:它的复合语句被认为已经退出),重用现有的异常对象:不创建新对象。

或者from [expr.throw]/3:

没有操作数的throw表达式会重新抛出当前处理的异常。用现有的异常对象重新激活异常;没有创建新的异常对象。该异常不再被认为是被捕获的。

作为旁白,是否有一个特殊的原因,你调用你的方法toString()而不是std::exception层次结构中使用的what() ?

最新更新