最近研究了boost中的ScopeExit,發(fā)現(xiàn)是個(gè)這是個(gè)很高級(jí)的特性,可以在作用域結(jié)束時(shí)自動(dòng)關(guān)閉已經(jīng)打開(kāi)的資源或做某些清理操作。
舉例: 如果沒(méi)有ScopeExit
void test () {
char *test = new char[100];
if (a) {
delete[] test; // count 1
return;
}
xxx;
if (b) {
delete[] test; // count 2
return;
}
xxx;
delete[] test; // count 3
}
使用了ScopeExit
void test () {
char *test = new char[100];
ScopeExit {
delete[] test; // 在test函數(shù)聲明周期結(jié)束后自動(dòng)執(zhí)行delete[]操作
};
if (a) {
return;
}
xxx;
if (b) {
return;
}
xxx;
}
當(dāng)然,正常C++代碼不鼓勵(lì)使用裸指針,可以使用智能指針來(lái)申請(qǐng)資源,這里只是舉個(gè)例子,使用ScopeExit也可以用于處理文件資源的關(guān)閉等等。
兩者代碼比較后優(yōu)劣程度顯而易見(jiàn),不使用ScopeExit需要在return前多次做資源清理操作,而使用了ScopeExit則只需做一次聲明后在作用域結(jié)束后會(huì)自動(dòng)進(jìn)行相關(guān)的資源清理操作,方便而且不易出錯(cuò)。
ScopeExit實(shí)現(xiàn)
這里參考boost使用C++11實(shí)現(xiàn)了一套ScopeExit機(jī)制
class ScopeExit {
public:
ScopeExit() = default;
ScopeExit(const ScopeExit&) = delete;
void operator=(const ScopeExit&) = delete;
ScopeExit(ScopeExit&&) = default;
ScopeExit& operator=(ScopeExit&&) = default;
template <typename F, typename... Args>
ScopeExit(F&& f, Args&&... args) {
func_ = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
}
~ScopeExit() {
if (func_) {
func_();
}
};
private:
std::function<void()> func_;
};
#define _CONCAT(a, b) a##b
#define _MAKE_SCOPE_(line) ScopeExit _CONCAT(defer, line) = [&]()
#undef SCOPE_GUARD
#define SCOPE_GUARD _MAKE_SCOPE_(__LINE__)
使用方式如下:
void test () {
char *test = new char[100];
SCOPE_GUARD{
delete[] test;
};
if (a) {
return;
}
xxx;
if (b) {
return;
}
xxx;
}