Scope Guard
Scope Guard
3通りほど方法がある(と思う)けど,どれがいいのか?
方策1
作れそうな気がしてScope Guardを作ってみたけど,
どっかで見たことあるなーと思ってたら案の定ここで読んだものでした. >http://d.hatena.ne.jp/faith_and_brave/20081212
これが普通のやり方. Boost(のdetail)に入ってるみたいだし.*1
// 推論した型Fを実装クラスの基底クラスに持っておき, // デストラクタでダウンキャストしてFを評価する. template<typename F> scope_guard::scope_guard(F f) : f_(new impl<F>(f)) {}
方策2
shared_ptrのデストラクタ指定を使う.
using namespace std; void End(string const & msg){ cout << "End call" << msg << endl; } int main(){ string msg("guard message"); boost::shared_ptr<void> guard(static_cast<void*>(0), boost::bind(End, msg)); cout << "main end" << endl; return (0); } // > main end // > End call guard message <- デストラクタで実行されるので後ろに来る
scoped_ptrが使えるならそちらの方が望ましいかも知れないけど,
重くしたくないのか,デストラクタが指定できない.
方策3
BOOST_SCOPED_EXITを使う.
bool atomic_behavior(){ std::string msg(" スコープ終了のお知らせ "); int x = 777; char cs[10]; bool ret=true; commit(msg, x); // コンマで区切らないで環境を渡す BOOST_SCOPE_EXIT( (&msg) (x) (&cs) ){ // 配列は'&'を付けるとキャプチャ出来る. if( isError() ){ rollback(); ret=false; } std::cout << msg << std::endl; } BOOST_SCOPE_EXIT_END /* ここで他の処理 */ // scope_exit発動 return (ret); }
boostの黒魔術だけどすごく便利 :)