轉載自(http://www.cnblogs.com/tonychen-tobeTopCoder/p/5222178.html
class ScopeGuard
{
public:
explicit ScopeGuard(std::function<void()> onExitScope)
: onExitScope_(onExitScope), dismissed_(false)
{ }
~ScopeGuard()
{
if (!dismissed_)
{
onExitScope_();
}
}
void Dismiss()
{
dismissed_ = true;
}
private:
std::function<void()> onExitScope_;
bool dismissed_;
private: // noncopyable
ScopeGuard(ScopeGuard const&);
ScopeGuard& operator=(ScopeGuard const&);
};
爲了在管理多個資源時不用花精力想變量名,可以定義幾個宏
#define SCOPEGUARD_LINENAME_CAT(name, line) name##line
#define SCOPEGUARD_LINENAME(name, line) SCOPEGUARD_LINENAME_CAT(name, line)
#define ON_SCOPE_EXIT(callback) ScopeGuard SCOPEGUARD_LINENAME(EXIT, __LINE__)(callback)
其中##是連接符,LINE是編譯器自帶的宏,指的是源代碼的行號。這樣就會自動生成變量名爲”EXIT行號”。
應用如下
class A {
public:
int a;
A(int i) :a(i) {}
};
void EraseA(A &a)
{
a.a = 0;
cout << "eraseA" << endl;
}
int main()
{
A a(2);
ON_SCOPE_EXIT([&] { EraseA(a); });
return 0;
}
程序結束時輸出 eraseA
Dismiss()函數作用是爲了支持rollback模式,例如:
ScopeGuard onFailureRollback([&] { /* rollback */ });
... // do something that could fail
onFailureRollback.Dismiss();
如果“do something”的代碼出錯,就執行析構函數中的rollback邏輯。如果代碼順利運行,就將dismissed_設爲true,這樣在退出作用域時就不會執行rollback操作了。
lambda表達式用於創建匿名函數對象語法格式如下
[捕獲列表] (函數參數) mutable或exception聲明 ->返回類型 {函數體};
捕獲列表是一個lambda所在函數中定義的局部變量的列表,可以爲空,上文的[&]表示默認使用引用傳值,如果用[=]則表示默認使用值傳遞。
最簡單的使用方法如下
auto f = [] {return 42;};
cout<<f()<<endl;
結果打印42。