C – 找到捕获的默认异常的类型

我有
try
{
 externalLibrary::doSomething();
}
catch (std::exception &e)
{
 //yay I kNow what to do
}
catch (...)
{
 //darn,I've no idea what happened!
}

可能有些情况下您会收到异常,并且您不知道来自哪里或为什么 – 在一些没有调试信息的外部库中.有没有办法找到被抛出的东西,或者获得与之相关的任何数据?他们可能在做:

throw myStupidCustomString("here is some really useful information");

但我永远不知道我是否抓住…

在MSVC 2008工作如果重要.

解决方法

因为C是静态类型的,你必须抓住已知的类型.但是,您可以调用外部函数(或一组函数),它们在您调用它们时处理异常类型未知.如果这些处理程序都具有已知类型,那么可以注册它们进行动态尝试.
struct myStupidCustomString {
  myStupidCustomString(char const *what) : what (what) {}
  char const *what;
};

void throws() {
  throw myStupidCustomString("here is some really useful information");
}

// The external library can provide a function,or you can provide a wrapper,which
// extracts information from "unkNown" exception types.
std::string extract_from_unkNown_external_exception() {
  try { throw; }
  catch (myStupidCustomString &e) {
    return e.what;
  }
  catch (...) {
    throw;  // Rethrow original exception.
  }
}

Use

void example() {
  try { throws(); }
  catch (...) {
    try {
      std::string extracted = extract_from_unkNown_external_exception();
      std::cout << "extracted: " << extracted << '\n';
    }
    catch (...) {
      // Chain handlers for other types; e.g. exception types from other libraries.
      // Or do something generic for the unkNown exception.

      // Or rethrow the original unkNown exception:
      throw;
    }
  }
}

Handler chain

typedef std::string Extract();
std::vector<Extract*> chain (1,&extract_from_unkNown_external_exception);
// Chain would normally be initialized using whatever scheme you prefer for
// initializing global objects.
// A list or other container (including a manual linked list that doesn't
// require dynamic allocation) may be more appropriate,depending on how you
// want to register and unregister handlers.
std::string process_chain() {
  for (std::vector<Extract*>::iterator x = chain.begin(); x != chain.end(); ++x) {
    try {
      return (*x)();
    }
    catch (...) {}  // That handler Couldn't handle it.  Proceed to next.
  }
  throw;  // None Could handle it,rethrow original exception.
}

void example() {
  try { throws(); }
  catch (...) {
    try {
      std::string extracted = process_chain();
      std::cout << "extracted: " << extracted << '\n';
    }
    catch (...) {
      throw;  // Rethrow unkNown exception,or otherwise handle it.
    }
  }
}

最后,如果您了解实现细节,可以使用它们来提取您的实现暴露的任何其他信息. C 0x也以便携式方式公开了一些细节;看看std :: exception_ptr.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...