しばらくして、私は何年も持っていたコーディングパターンに気付き、それが私を緊張させます。私は特定の問題はありませんが、なぜ私がそのパターンを採用したのかについても十分に覚えていないし、その一部のパターンはいくつかのアンチパターンと一致するようです。これは最近私のコードのいくつかが例外をどのように使っているのか私には起こりました。私はC++のcatch節、例外クラスのファミリ、および破棄を使用していますか?
気になることは、 "参照によって"例外をキャッチし、パラメータを関数にどのように扱うかと同じように扱う場合です。これを行う理由の1つは、例外クラスの継承階層を持つことができ、アプリケーションに応じてより一般的な、またはより正確なキャッチタイプを指定できることです。例えば、私はp_Exception経由...
class widget_error {};
class widget_error_all_wibbly : public widget_error {};
class widget_error_all_wobbly : public widget_error {};
void wibbly_widget()
{
throw widget_error_all_wibbly();
}
void wobbly_widget()
{
throw widget_error_all_wobbly();
}
void call_unknown_widget (void (*p_widget)())
{
try
{
p_widget();
}
catch (const widget_error &p_exception)
{
// Catches either widget_error_all_wibbly or
// widget_error_all_wobbly, or a plain widget_error if that
// is ever thrown by anything.
}
}
これは(私は関数内(スローの一部として)クラスのインスタンスが構築されることに気付きましたので、今私を心配されますが、参照されている定義できますキャッチ節 "パラメータ")を呼び出すことができます。これは通常、アンチパターンです - ローカル変数への参照またはポインタ、または関数内で作成された一時的なものですが、関数が終了すると渡されます。通常、ローカル変数/ temporaryが破棄され、関数が終了するとき。
いくつかの簡単なテストでは、スロー句で作成されたインスタンスは、関数が終了すると破棄されず、それを処理するcatch節が完了すると破棄されます。ただし、catchブロックが再スローされない限りこの場合、次のcatchブロックがこのジョブを行います。
私が残っている緊張感は、1つまたは2つのコンパイラでテストを実行すると、標準が何を示すのかという証拠ではなく、私の経験から言えば、言語が保証するものとは異なることが多いからです。
このように、例外を処理する(参照型を使用してキャッチする)このパターンは安全ですか?または、私は他の何かをする必要がありますか...
- ヒープ割り当てインスタンスへのポインタをキャッチ(明示的に削除)します。
- スマートポインタクラスを使用していますか?
- "値渡し" catch句を使用し、1つのcatch句を持つ階層から例外クラスをキャッチできないことを受け入れるか?
- 私が考えなかったことは何ですか?
[仮想継承を使用](http://www.boost.org/community/error_handling.html)。 – ybungalobill
@ybungalobill - 私はそれが冗談だと思ったが、私はそのリンクを読んだ。興味深い点。 – Steve314