6

我有一组函数,需要将可能抛出的异常转换为错误代码。

为此,我使用 try/catch 语句包装了实际调用:

int f_with_error_codes()
{
  try {
    f(); // wrapped function call

    return E_SUCCESS;
  }
  catch (error1&) {
    return E_ERROR1;
  }
  catch (error2&) {
    return E_ERROR2;
  }
}

int g_with_error_codes(int a);
{
  try {
    G g(a);        // wrapped expressions
    g.print();

    return E_SUCCESS;
  }
  catch (error1&) {
    return E_ERROR1;
  }
  catch (error2&) {
    return E_ERROR2;
  }
}

...

这些 catch 语句会重复。此外,每当添加新异常时,都必须将新的 catch 子句添加到每个调用包装器中。

像下面这样用于替换catch语句的宏是否合适?

#define CATCH_ALL_EXCEPTIONS  \
catch (error1&) {             \
  return E_ERROR1;            \
}                             \
catch (error2&) {             \
  return E_ERROR2;            \
}

这将导致:

int f_with_error_codes()
{
  try {
    f(); // the wrapped

    return E_SUCCESS;
  }
  CATCH_ALL_EXCEPTIONS
4

2 回答 2

10

您可以使用函数代替宏,如下所示:

int f_with_error_codes() 
{ 
  try { 
    f(); // wrapped function call 

    return E_SUCCESS; 
  } 
  catch (...) { 
    return error_code();
  } 
}

int error_code()
{
  try { 
    throw;
  } 
  catch (error1&) { 
    return E_ERROR1; 
  } 
  catch (error2&) { 
    return E_ERROR2; 
  } 
}
于 2012-10-22T09:13:25.117 回答
7

对于您的情况,您不需要任何宏。
只需一个包含virtual函数的简单基类就足够了。

class error : public std::exception { // std::exception is your wish
  const char* what () throw(); // needed if std::exception is based
  virtual int GetValue () const = 0;  // <--- This is the core part
}

现在,用所有类继承这个error#类:

class error1 : public error {
  virtual int GetValue () const { return E_ERROR1; } // <--- override
};
// ...

最后,您的代码就像这样简单:

void f_with_error_codes()
{
  try {
    f(); // wrapped function call
    return E_SUCCESS;
  }
  catch (error& e) {  // <--- base handle
    return e.GetValue();
  }
}

不用担心virtual这里的功能成本。因为它是最小的,而且例外是罕见的事件;virtual使您的代码可维护和可扩展的成本非常低。

于 2012-10-22T09:00:46.887 回答