私は数年前にAndrei AlexandrescuとPetru Margineanによって書かれたthis articleに出くわしました。例外安全コードを書くためのScopeGuardというユーティリティクラスを紹介しています。私は、これらのオブジェクトを使ってコーディングした方が本当に良いコードにつながるのか、それともエラー処理を難読化するのかを知りたいのですが、おそらくガードのコールバックがキャッチブロックでよりよく提示されるでしょうか?実際のプロダクションコードでこれを使っている人はいますか?ScopeGuardは本当により良いコードにつながりますか?
答えて
これは間違いなくコードを改善します。 RAIIが確立されたイディオムであるため、あなたの暫定的に公式化された主張、それはあいまいであり、コードはcatch
ブロックからメリットを得ることはC++では真実ではありません。 C++でのリソース処理は、リソース取得によって行われたであり、ガベージコレクションは暗黙のデストラクタ呼び出しによって行われます。
一方、明示的なcatch
ブロックは、コードフローがはるかに複雑になり、リソース処理を明示的に行わなければならないため、コードを膨らませ微妙なエラーを招きます。
RAII(ScopeGuard
を含む)は、C++ではあまり知られていませんが、確かに確立されたベストプラクティスです。
+1現代的なC++テクニックに固執します。また、AlexandrescusがScopeGuardの新しいバージョンを提供していることにも注意してください。http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in -Cははるかに使いやすいです。ミッチは編集する価値がある。 – odinthenerd
私はこの特定のテンプレートを使用していませんが、これまでに同様のものを使用しました。はい、さまざまな方法で実装された同様に堅牢なコードと比べると、より明確なコードにつながります。
私はしばしば、メモリ使用を守るために、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++プログラマーが10分の学習に励むことができるC++コードが1つあれば、それはScopeGuard(現在は無料で利用できるLoki libraryの一部です)です。
私が取り組んでいた小さなWin32 GUIプログラムのために、ScopeGuardの(少し修正された)バージョンを使用しようと決めました。あなたが知っているかもしれないWin32には、さまざまな方法で閉じなければならないさまざまなタイプのリソースがあります(例えば、カーネルハンドルは通常CloseHandle()
で閉じ、GDI BeginPaint()
はEndPaint()
などとペアにする必要があります)。 new
(例えば、Unicodeとの/からの文字セット変換)のワーキングバッファを割り当てるためにも使用します。
私が驚いたのは、どれくらいでしたか短くでした。基本的に、それは勝利です:あなたのコードは、同時に短くて堅牢になります。将来のコード変更は何もリークできません。彼らはできません。それはどれくらい涼しいですか?
Downvoter:コメントしますか? –
私は、いいえ、そうではありません。ここの答えは、なぜそれが本当にひどいアイデアなのかを示すのに役立ちます。リソースの再利用は、再利用可能なクラスを使用して行う必要があります。スコープガードを使用して達成した唯一のことは、リソースを処理するクラスを作成するのではなく、リソース全体をコードベースで複製することです。
スコープガードは、実際の用途を持っている場合は、リソースの取り扱いはそれらのではない一つです。 RAIIは重複排除され、自動化され、スコープガードは手作業によるコードの重複またはバストであるため、その場合は普通のRAIIに比べて大幅に劣っています。
上記の回答には重要なメモが1つもないと思います。他の人が指摘しているように、障害(例外)から独立して割り当てられたリソースを解放するためにScopeGuard
を使用することができます。しかし、それはスコープガードを使用したいかもしれない唯一のものではないかもしれません。実際、リンクされた記事の例では、異なる目的のためにScopeGuard
を使用しています。要するに、RAIIを適切に使用しているオブジェクトであっても、複数のオブジェクトがある場合には、何らかの形で関連付けられた状態を保つ必要がある場合に便利です。これらのオブジェクトのいずれかの状態の変更によって例外が発生した場合(通常、その状態が変更されなかったことを意味します)、すでに適用されているすべての変更をロールバックする必要があります。これにより、それ自身の問題が発生します(ロールバックが失敗した場合はどうなりますか?)。そのような相関オブジェクトを管理する独自のクラスを展開しようとする可能性がありますが、その数が増えれば乱雑になり、とにかくScopeGuard
を内部的に使用することになります。
はい。
Dでそれのためにも、特別な構文ということは、C++でとても重要だった:
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
}
- 1. レイトレーシングについては本当に良い本がありますか?
- 2. Mooseへの移行に本当に良いウェブリソースがありますか?
- 3. シンプルなリッチテキストエディタの作成方法については、本当に基本的なチュートリアルはありますか?
- 4. ここに本当に必要なバンパターンがありますか?
- 5. window.navigator.userAgentは本当に推奨されなくなりますか?
- 6. カーソルは本当にどれくらい遅く、より良い選択肢になるでしょうか?
- 7. IDEは本当に価値がありますか?
- 8. GRASP Creatorは本当に切り離していますか?
- 9. PropertyInfo.DeclaringTypeが本当にnullになることはありますか?
- 10. Grepには本当に普遍的なワイルドカードがありますか?
- 11. ascxとcodebehindの間にイベントハンドラを割り当てることには本当に違いはありますか?
- 12. このコードを書くより良い方法はありますか?非常に醜いコードですか?
- 13. Apache Benchmarksは本当に悪いですが、アドバイスはありますか?
- 14. OpenLayersにはどのような本がありますか?
- 15. Java Webフレームワークは本当に面倒な価値がありますか?
- 16. 本当に最初から始まる良いiPhone SQLite3チュートリアルはありますか?
- 17. 割り込みハンドラの中にprintkがありますが、それは本当に悪いですか?
- 18. 教育目的のために、本当にきれいでクリアな[R]コードの良い例は何ですか?
- 19. OracleドライバはJDBC4と本当に互換性があります
- 20. ハッキングはあなたをより良いプログラマーにしますか?
- 21. Djangoは、モデルに別のモデルへのForeignKeyがないと言っていますが、本当にあります
- 22. 安全なコードを書く。毎回割り当てエラーを本当にチェックしますか?
- 23. Admob、本当に悪い塗りつぶし
- 24. 本当にナンスを使う必要はありますか?
- 25. 本当に普遍的なデータリンクはどこにありますか?
- 26. Iphoneいつ操作キュースレッドが本当に開始しますか?
- 27. より良いgoogle/yahoo/bing検索のためにデータベースよりもフラットファイルにコンテンツを保存するのは本当に便利ですか?
- 28. Cocoa MVCは本当にMVPではありませんか?
- 29. コアデータの移行は本当に遅いですが、なぜそれはまったく起こりますか?
- 30. Cの基本コードが期待通りに動作しない
C++ 0xの/ C++ 11は今 "shared_ptrの" とのことありません。 –
私はそれがあなたにもっと力を与えるのを見ます。データベースの例はかなり良いです。 shared_ptrを使用すると、ScopedGuardを使用している間は通常は接続を閉じるデストラクタが呼び出されます。例外の場合は実際にロールバックすることができます。 –