最近、Scope Guard C++ イディオムについて学びました。残念ながら、私はそれの良い実装を見つけることができません。
C++ での適切で使用可能なスコープ ガードの実装を教えてもらえますか?
ありがとう、ボダ・シド。
オリジナルのScopeGuardクラスは、AndreiAlexandrescuとPetruMargineanによるこのDr.Dobbの記事に含まれています。Joshua Lehrerからのいくつかの変更を加えた、わずかに改善されたバージョンは、ここから入手できます。(Lehrerのバージョンは、私のプロジェクトで使用しているバージョンです。)これはLokiライブラリにも含まれています。
Boostには、ScopeGuardよりも強力なScopeExitライブラリが追加されました(任意のコードを実行できるのに対し、ScopeGuardは既存の関数を1つしか呼び出せないため)。
編集:そうは言っても、スコープガードは実際にはRAIIの特定のアプリケーションにすぎないため、少なくとも実装方法の概念を理解する必要があります。
ScopeGuard はLokiライブラリ (Andrei Alexandrescu による Modern C++ Design で宣伝されています。この素晴らしい本について聞いたことがあると思います) に含まれており、製品コードで使用できるほど成熟しています。
明確にするために: RAII を使用して例外セーフ コードを記述することについて話しているのです。
追加資料 (StackOverflow について): ScopeGuard の使用は本当に優れたコードにつながるのか?
MNMLSTC コアには、スコープ ガード イディオムの最新の C++11 実装があります。
「スコープ ガード」オブジェクトは、より広範なRAIIイディオムの 1 つのインスタンスにすぎません。
そして、それの単一の実装はありません。これは、コピー/貼り付けだけでなく、C++ プログラマーが理解しなければならないことです。幸いなことに、実装も非常に簡単です。
ある種のリソースを表すクラスを作成します。クラスが (そのコンストラクターの 1 つによって) インスタンス化されると、リソースを取得し、それが失敗した場合は例外をスローする必要があります。クラスが破棄されると、必要なすべてのクリーンアップを実行して、リソースを破棄する必要があります。
以上です。また、コピー コンストラクターと代入演算子を処理する必要があります (リソースを複製するか、これら 2 つの関数をプライベートにして、呼び出されないようにする必要があります)。
「良い実装」を見つける必要はありません。自分で何十もの異なる実装を作成することになるからです。それらは簡単に書くことができ、それぞれが異なるタイプのリソースをラップするため、簡単に再利用することはできません。
標準ライブラリに scope_guard を追加するという提案があります。コピーして貼り付けることができるサンプル実装を含む論文は、こちらで読むことができます。実装については、セクション 9.1 を参照してください。