我正在尝试编写代码,该代码在发生错误时传递处理程序。
class Handler {
public: virtual void handle(std::exception const& e) = 0;
};
class DoIt {
Handler* handler;
public:
void doStuff() {
try {
methodThatMightThrow();
} catch (std::exception const& e) {
handler->handle(e);
}
}
void setHandler(Handler* h) { handler = h; }
void methodThatMightThrow();
}
不同的项目将使用此类具有不同的错误处理技术。
项目1记录错误
class Handler1: public Handler {
void handle(std::exception const& e) override {
logError(e.what());
}
};
Project 2传播异常
class Handler2: public Handler {
void handle(std::exception const& e) override {
throw e;
}
};
这两个都应该有用。但是,如果异常是Handler2
的子类,std::exception
将抛出异常的副本并丢失任何派生类信息,这几乎肯定是。
是否有一种好方法可以重新抛出原始异常,甚至是同一类型的副本?
答案 0 :(得分:1)
问题是你不能抛出引用。投掷需要对象的真实副本。副本正在将引用切换为throw处的类型。
我不知道这个问题的解决方法。
答案 1 :(得分:1)
您可以使用裸throw
来重新抛出当前异常。
重写Handler2
以使用此功能将提供以下代码:
class Handler2 : public Handler
{
public: void handle(const std::exception& ex) const override
{
throw;
}
};
您不必将异常作为参数发送,并且可以编写更多高级处理程序,这些处理程序可以执行不同的操作,具体取决于异常类型,例如此简单处理程序。
class WrapperHandler : public Handler
{
public:
void handle() const
{
try
{
throw;
}
catch (const notveryserious_exception& ax)
{
std::cout << "Not very serious, I'm going to let this slide." << std::endl;
std::cout << ax.what() << std::endl;
}
catch (const myown_exception& ax)
{
// Probably serious, will let this propagate up the stack.
throw;
}
catch (...)
{
// Bad, bad, bad.. Unhandled exception that we haven't thrown ourselves.
throw myown_exception("Unhandled exception.");
}
}
};