你能将一个异常继承层次结构包装成另一个吗? - 或者,另一个干净的方式处理这个?

时间:2013-03-28 21:46:27

标签: c++ stl

假设我有两个我在C ++中处理的继承层次结构。一个继承自std::exception(新层次结构),另一个继承自Exception(旧版C ++ Builder VCL基本异常类)。如果我调用可能抛出任何类型异常的代码,我必须编写如下代码:

try {
    // do stuff....
    Function1();
    Function2();
} catch (std::exception &ex) {
    std::cout << "STL exception caught: " << ex.what() << std::endl;
} catch (Exception &ex) {
    std::cout << "Legacy exception caught: " << ex.Message.c_str() << std::endl;
} catch (SomeOtherVendorLibraryException &ex) {
    // etc.
}

问题是每个调用者都需要拥有所有这些catch子句来尝试获取每个最后一种类型的异常,因为C ++没有一个真正的强制异常基类可以用作全能(例如{{1 C#中的类。 (System.Exception是一个非首发,因为你没有办法知道你抓到了什么,并且一些危险的系统异常,例如访问冲突,也可能被捕获,最好不要被捕获。)

我想将这些“遗留”异常包装到catch (...)层次结构中的类中。将第三方异常包装到您自己的异常系统中的概念并非完全前所未有。例如,.NET Framework在其他系统中包含大量错误(例如std::exception)。理想情况下,我希望看到这样的事情:

COMException

可以理解的是,异常从未被捕获 - 它会从编译器中获得相当多的魔力来捕获它。

是否有可能与上述类似的解决方案包装遗留异常并实现这些目标?

  • 一个“catch”子句或类似子句,因此一般的异常处理逻辑只需要写一次。
  • 必须集中处理从一种例外类型转换为另一种例外类型的逻辑。
  • 如果可能,请避免使用宏。
  • 不使用lambda函数。

1 个答案:

答案 0 :(得分:2)

在使用BC ++ Builder之后,我遇到了同样的问题,而宏似乎是当时唯一的解决方案。

“clean”(hum ...)解决方案可能是一个“双重尝试 - 捕获”:内部try-catch将您的遗留异常转换为标准类,而外部异常实际上处理异常。

我手边没有代码(已经过了好几年),但基本上归结为:

#define DTRY  try { try
#define DCATCH catch (Exception& e) { throw LegacyException(e); } } catch

DTRY {
   ...
}
DCATCH(std::exception& e) {
    // handle the exception
}

是的,我知道这很难看,但是当我和Borland合作时,我找不到更好的东西。事实上,当时Borland非常不标准,我不知道它是如何演变的,也许你现在可以做得更好。希望这无论如何都有帮助。