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ステートメントを置き換えるための以下のようなマクロは適切ですか?

#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 に答える