exception处理中的代码重用

我正在为用C ++编写的一些function开发一个C api,我想确保没有任何exception从任何导出的C函数中传播出来。

这样做的简单方法是确保每个导出的函数都包含在:

try { // Do the actual code } catch (...) { return ERROR_UNHANDLED_EXCEPTION; } 

假设我知道在C ++代码中经常遗漏的一个exception是std :: bad_alloc,我想特别对待它我会写这样的东西:

 try { // Run the actual code } catch (std::bad_alloc& e) { return ERROR_BAD_ALLOC; } catch (...) { return ERROR_UNHANDLED_EXCEPTION; } 

是否有可能以一种巧妙的方式对其进行分解,以便我可以全局处理一些错误而不为每个导出函数添加一个新的catch语句用于exception处理程序?

我知道使用预处理器可以解决这个问题,但在走这条路之前,我确保没有别的方法可以做到这一点。

对于所有可能的exception,您只能使用一个处理函数,并从每个或您的API实现函数中调用它,如下所示:

 int HandleException() { try { throw; } // TODO: add more types of exceptions catch( std::bad_alloc & ) { return ERROR_BAD_ALLOC; } catch( ... ) { return ERROR_UNHANDLED_EXCEPTION; } } 

并在每个导出的function:

 try { ... } catch( ... ) { return HandleException(); } 

已经有了一个很好的答案。 但仅仅是FYI,它被称为“exception调度程序”的成语,请参阅C ++ FAQ 。

关于什么:

 try{ //Your code here } catch(std::exception e) { return translateExceptionToErrorCode(e); } catch(...) { return UNKNOWN_EXCEPTION_THROWN; } 

Jem的回答比这个解决方案简单得多。 但是可以使用模板替换预处理器宏的使用。 这样的事情(你可以做的更多改进):

 template  class CatchWrapper { public: static void WrapCall(T* instance) { try { (instance->*FUNC)(); } catch (std::bad_alloc&) { // Do Something 1 } catch (std::exception& e) { // Do Something 2 } catch (...) { // Do Something 3 } } }; class Foo { public: void SomeCall() { std::cout << "Do Something" << std::endl; } }; int main(int argc, char* argv[]) { Foo i; CatchWrapper::WrapCall(&i); return 0; } 

不要使用catch(...) ,除非你计划或多或少立即重新投掷。 您肯定会丢失任何错误信息,以帮助您找出错误原因。

我更喜欢你的第二个方案 – 捕获一组已知的exception,理想情况是因为它们是你的代码将抛出的唯一exception,让剩下的通过 – 允许应用程序崩溃可能是最好的事情,因为你已经调用不明行为最好“负责任地崩溃”。

在语言边界丢失错误信息将是一种耻辱。 您真的应该尝试将所有exception转换为可从C中使用的错误代码。

你如何做到这一点真的取决于你的exception类是什么样的。 如果控制exception类层次结构,则可以确保每个类都使用虚方法提供转换。 如果没有,你仍然可以发现使用翻译函数并测试它收到的’std :: exception’派生的exception的类型以将其转换为错误代码是很实际的,就像Jem建议的那样(记住:抛出exception会伤害无论如何都要表现,所以不要担心翻译速度慢。