2012-10-22 3 views
5

私は一連の関数を持っており、スローされる可能性のある例外を エラーコードに変換する必要があります。別の場所で一連の例外を捕捉するマクロは問題ありませんか?

は、この目的を達成するために、私は、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; 
    } 
} 

... 

これらのキャッチstatmementsが自分自身を繰り返します。さらに、新しい例外 が追加されるたびに、新しい呼び出し句を各呼び出しラッパーに追加する必要があります。

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 
+0

なぜ私は適切ではないでしょうか?それはあなたのコードを正しく書く方法に依存しますか? –

+1

@markus_pであり、後の時点でどのように他のコードを読み込むか(保守性)によっても異なります。 – iammilind

+0

@iammilind trueですが、g_with_error_codesは実際にこれらのすべて(可視性)を既に無効にしています。この場合、マクロはソースに掘り下げた人の目にだけ見えます。 –

答えて

9

代わりに、このようなマクロの機能を使用することができます。

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; 
    } 
} 
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の非常に小さなコストは、コードをメンテナンス可能かつ拡張可能にするための価値があります。

+1

ありがとうございました。私はむしろ、使用されている例外構造を変更することはしませんが、あなたの答えは例外クラスを変更できる人にとって価値があると思います。 –

関連する問題