あなたが巻き込まれているように見えるのは、ケーキを持って食べようとする誰かの特定の地獄です。
RAIIと例外は、連動するように設計されています。RAIIは、あなたがしない手段である必要があり、多くの書き込みにcatch(...)
クリーンアップを実行するステートメントを。もちろん、それは自動的に行われます。また、例外はRAIIオブジェクトを操作する唯一の方法です。コンストラクターは成功またはスロー(またはオブジェクトをエラー状態にするが、だれがそれを望むのか)しかできないためです。
catch
文は、2つのいずれかの操作を行うことができますエラーまたは例外的な状況を扱う、またはクリーンアップ作業を行います。両方catch
を実行することもありますが、これらの少なくとも1つを実行するためのすべてのステートメントが存在します。
catch(...)
適切な例外処理を行うことができません。例外が何なのかわかりません。例外に関する情報を取得できません。特定のコードブロック内の何かによって例外がスローされたという事実以外の情報はまったくありません。このようなブロックでできる唯一の正当なことは、クリーンアップを行うことです。そして、それはクリーンアップの終わりに例外を再スローすることを意味します。
例外処理に関してRAIIが提供するのは、無料のクリーンアップです。すべてが適切にRAIIカプセル化されている場合、すべてが適切にクリーンアップされます。catch
ステートメントをクリーンアップする必要はもうありません。その場合、catch(...)
ステートメントを記述する理由はありません。
だから私はそれcatch(...)
がほとんど悪であることに同意するだろう... 暫定的に。
その規定はRAIIの適切な使用です。それなしでは、特定のクリーンアップを実行できる必要があります。それを回避することはありません。クリーンアップ作業を行える必要があります。例外をスローすると、コードが適切な状態になるようにする必要があります。そして、catch(...)
ある重要なそうすることでツール。
片方をもう片方なしに持つことはできません。RAII も悪いと catch(...)
も言えません。これらのうち少なくとも1つが必要です。そうでなければ、あなたは例外的に安全ではありません。
もちろん、catch(...)
RAIIでさえも消去できない有効な、しかしまれな使い方が1つありexception_ptr
ます。それは、誰かに転送することです。通常、promise/future
または同様のインターフェースを介して。
私の同僚は、どの例外がスローされるかを常に知っておく必要があり、次のような構造を常に使用できると言っています。
あなたの同僚はバカです(またはひどく無知です)。これは、彼があなたに書くことを提案しているコピーアンドペーストコードの量のためにすぐに明らかになるはずです。これらの各catchステートメントのクリーンアップはまったく同じになります。可読性は言うまでもなく、メンテナンスの悪夢です。
つまり、これはRAII が解決するために作成された問題です(他の問題を解決しないわけではありません)。
この概念について私を混乱させるのは、ほとんどの人がRAIIが悪いと主張する方法に一般的に逆行しているということです。一般に、引数は「RAIIは、コンストラクターの失敗を通知するために例外を使用する必要があるため悪い。しかし、安全ではなく、catch
すべてをクリーンアップするために多くのステートメントが必要になるため、例外をスローできない」。RAII はRAIIの欠如が引き起こす問題を解決するため、これは壊れた議論です。
おそらく、彼はRAIIに反対しています。なぜなら、それは詳細を隠すからです。デストラクタの呼び出しは、自動変数ではすぐには表示されません。したがって、暗黙的に呼び出されるコードを取得します。一部のプログラマーは本当にそれを嫌います。どうやら、彼らが3つのcatch
ステートメントを持っていると考えるポイントまでは、コピーアンドペーストコードですべて同じことを行うのが良い考えです。
...
、私の質問は「キャッチする必要があります...
か<specific exception>
、再スローする前に」に焦点を当てています