Boost.ScopeExit

在C++中RAII是很常用的手法,但在一些情況下要多花不少時間去包裝,在Boost中有提供了 ScopeExit (http://www.boost.org/doc/libs/1_57_0/libs/scope_exit/doc/html/index.html),在一些應用下會比正規的 RAII 更加好用。

 

以 Boost.ScopeExit 官方範例來看,它希望在 addPerson() 中如果有任何一行程式碼失敗了,可以做到 strong guarantee,因此要把 aPerson 從 一_persons中 pop_back() 出來。如果不用 ScopeExit,可以想見在很多地方都會存在著 if(!commit) {m_persons.pop_back()} 這種片段,但有了ScopeExit 就可以有效解決這個問題。

 

void World::addPerson(Person const& aPerson) {

 

bool commit = false;

m_persons.push_back(aPerson); // (1) direct action


BOOST_SCOPE_EXIT( (&commit)(&m_persons) )

{

    if(!commit)

        m_persons.pop_back(); // (2) rollback action

} BOOST_SCOPE_EXIT_END

 

// … // (3) other operations

[這有可能會有一些失敗的動作,然後就 return / throw exception,然後便自動進入BOOST_SCOPE_EXIT]

...

...

commit = true; // (4) turn all rollback actions into no-op

[就算成功 commit 了,也還是會進入 BOOST_SCOPE_EXIT,但因為有判斷 if(!commit),所以不會進行 pop_back()]

}

 

BOOST_SCOPE_EXIT()到 BOOST_SCOPE_EXIT_END 中間的程式碼會在離開這個 scope 時被執行,因此可以把 cleanup 相關程式碼放在這裡頭。

以上面這段官方範例來說,它會在最後檢查如果 commit == false,則 pop_back() 剛才 push_back() 進去的 aPerson object。

PS.必需把要用到的變數都寫在 BOOST_SCOPE_EXIT() 的參數列中,才可以存取這些變數。

這篇文章寫的很詳細,值得一讀:

http://boost.cowic.de/rc/pdf/scope_exit.pdf

Share:

0 comments