Andrei Alexandrescu と Petru Marginean によって何年も前に書かれたこの記事に出くわしました。この記事では、例外セーフ コードを作成するための ScopeGuard と呼ばれるユーティリティ クラスを紹介し、説明しています。これらのオブジェクトを使用したコーディングが本当により良いコードにつながるのか、それともエラー処理を難読化するのかを知りたいのですが、おそらくガードのコールバックは catch ブロックでより適切に提示されるでしょうか? 実際の製品コードでこれらを使用した経験がある人はいますか?
8 に答える
それは間違いなくあなたのコードを改善します。RAIIは確立されたイディオムであるため、C ++では、それが曖昧であり、コードがcatch
ブロックからメリットを得るという暫定的に定式化された主張は、単に真実ではありません。C++ でのリソース処理はリソースの取得によって行われ、ガベージ コレクションは暗黙的なデストラクタ呼び出しによって行われます。
一方、明示的なcatch
ブロックは、コード フローがはるかに複雑になり、リソースの処理を明示的に行う必要があるため、コードが肥大化し、微妙なエラーが発生します。
RAII ( ScopeGuard
s を含む) は C++ のあいまいな手法ではなく、しっかりと確立されたベスト プラクティスです。
はい。
すべての C++ プログラマーが 10 分間学習することをお勧めできる C++ コードが 1 つあるとすれば、それは ScopeGuard (現在、無料で入手できるLoki ライブラリの一部) です。
私が取り組んでいた小規模な Win32 GUI プログラム用に、ScopeGuard の (わずかに変更された) バージョンを使用してみることにしました。ご存知かもしれませんが、Win32 には、さまざまな方法で閉じる必要があるさまざまな種類のリソースがあります (たとえば、カーネル ハンドルは通常 で閉じる必要がありCloseHandle()
、GDIBeginPaint()
は とペアにする必要があるEndPaint()
など)。これらすべてのリソースで ScopeGuard を使用し、割り当てにも使用しました。作業バッファnew
(たとえば、Unicode との間の文字セット変換用)。
私が驚いたのは、プログラムがどれだけ短いかということでした。 基本的に、これは双方にメリットがあります。つまり、コードが短くなり、同時に堅牢になります。将来のコード変更は何もリークできません。彼らはただできません。それはどれほどクールですか?
私はよくメモリ使用量を保護するためにそれを使用します。OSから返された解放する必要があるものです。例えば:
DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;
CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
Guard guardBlob=guardFn(::LocalFree, blobOut.pbData);
// do stuff with blobOut.pbData
はい。
C++ では非常に重要だったので、D では特別な構文でさえ次のようになりました。
void somefunction() {
writeln("function enter");
// c++ has similar constructs but not in syntax level
scope(exit) writeln("function exit");
// do what ever you do, you never miss the function exit output
}
この特定のテンプレートを使用したことはありませんが、似たようなものを以前に使用したことがあります。はい、さまざまな方法で実装された同等に堅牢なコードと比較すると、コードがより明確になります。