【问题标题】:Is it possible to pass an exception to a handler and then rethrow the original exception?是否可以将异常传递给处理程序,然后重新抛出原始异常?
【发布时间】:2015-02-24 20:42:40
【问题描述】:

我正在尝试编写代码,该代码在发生错误时传递给处理程序。

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());
  }
};

项目 2 传播异常

class Handler2: public Handler {
  void handle(std::exception const& e) override {
    throw e;
  }
};

这两个都应该有效。但是,如果异常是 std::exception 的子类,Handler2 将抛出异常的副本并丢失任何派生类信息,它几乎可以肯定是。

有没有很好的方法来重新抛出原始异常,甚至是相同类型的副本?

【问题讨论】:

标签: c++ exception-handling


【解决方案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.");
        }
    }
};

【讨论】:

    【解决方案2】:

    问题是你不能抛出一个引用。 Throw 需要对象的真实副本。副本在抛出点对类型的引用进行切片。

    我不知道解决此问题的方法。

    【讨论】:

    • 它可以抛出动态分配的异常对象。然后,catch 是指向异常的指针。这将解决切片问题。
    猜你喜欢
    • 2015-10-26
    • 2010-11-06
    • 2011-10-10
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多