繁体   English   中英

如何通过其运行时类型抛出异常?

[英]How to throw an exception by its run-time type?

我想调用一个可能抛出异常的函数。 如果它确实抛出异常,我想捕获它并将异常对象传递给处理函数。 处理函数的默认实现只是抛出异常。 以下是用于说明问题的削减代码:

struct base_exception : exception {
  char const* what() const throw() { return "base_exception"; }
};

struct derived_exception : base_exception {
  char const* what() const throw() { return "derived_exception"; }
};

void exception_handler( base_exception const &e ) {
  throw e; // always throws a base_exception object even if e is a derived_exception
}

int main() {
  try {
    throw derived_exception();
  }
  catch ( base_exception const &e ) {
    try {
      cout << e.what() << endl; // prints "derived_exception" as expected
      exception_handler( e );
    }
    catch ( base_exception const &e ) {
      cout << e.what() << endl; // prints "base_exception" due to object slicing
    }
  }
}

但是, exception_handler()throw e exception_handler()的静态类型的副本,即base_exception 如何使exception_handler()抛出具有正确运行时类型的derived_exception实际异常? 或者我如何重新设计东西以获得我想要的东西?

您可以将throw_me虚函数放在基本异常类中,并让每个派生类覆盖它。 派生类可以抛出适当的派生类型,而不进行切片。 即使函数在每个类中具有相同的定义,它们也不相同 - *this的类型在每种情况下都不同。

struct base_exception : exception
{
  char const* what() const throw() { return "base_exception"; }
  virtual void throw_me() const { throw *this; }
};

struct derived_exception : base_exception
{
  char const* what() const throw() { return "derived_exception"; }
  virtual void throw_me() const { throw *this; }
};

void exception_handler( base_exception const &e ) {
  e.throw_me();
} 

你可以使用throw; 重新抛出被捕获的异常。 您也可以使用模板。

template<typename T> void rethrow(const T& t) { throw t; }

按价值投掷,以参考方式捕获 它会为你省去很多麻烦。

您正在寻找的是被称为“传播”异常。 为此,您必须在catch块中使用不带参数的throw关键字。 它不会复制异常,异常将被下一个catch块捕获,或者如果没有再次捕获,将使程序中止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM