欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

巧妙使用RAII中的ScopeExit

 更新時(shí)間:2021年05月06日 17:11:17   作者:程序喵大人  
Resource Acquisition Is Initialization,資源獲取即初始化,將資源的生命周期與一個(gè)對(duì)象的生命周期綁定,這篇文章主要介紹了巧妙使用RAII中的ScopeExit,需要的朋友可以參考下

什么是RAII

Resource Acquisition Is Initialization,資源獲取即初始化,將資源的生命周期與一個(gè)對(duì)象的生命周期綁定,舉例來說就是,把一些資源封裝在類中,在構(gòu)造函數(shù)請(qǐng)求資源,在析構(gòu)函數(shù)中釋放資源且絕不拋出異常,而一個(gè)對(duì)象在生命周期結(jié)束時(shí)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),即資源的生命周期與一個(gè)對(duì)象的生命周期綁定。

RAII的應(yīng)用

見如下代碼:

std::mutex mutex;
void func() {}
void NoRAII() {
    mutex.lock();
    func();
    if (xxx) {
        mutex.unlock();// 多次需要調(diào)用unlock(),還有可能忘記調(diào)用unlock導(dǎo)致一直持有鎖
        return;
    }
    ...
    mutex.unlock();
}
void RAII() { // 不需要顯式調(diào)用unlock
    std::lock_guard<std::mutex> lock(mutex);
    func();
    if (xxx) {
        return;
    }
    ...
    return;
}

RAII的應(yīng)用非常多,C++的STL基本都遵循RAII規(guī)范,典型的如vector, string, lock_guard, unique_lock, shared_ptr, unique_ptr等,這里不會(huì)介紹這些STL的使用,相信大家也都會(huì)使用,如果有相關(guān)需求可以留言。

RAII的巧用

最近研究了boost中的ScopeExit,發(fā)現(xiàn)這是個(gè)很高級(jí)的特性,利用RAII特性,可以在作用域結(jié)束時(shí)自動(dòng)關(guān)閉已經(jīng)打開的資源或做某些清理操作,類似于unique_ptr,但又比unique_ptr方便,不需要自定義delete函數(shù)。
舉例: 如果沒有ScopeExit

void test () {
    char *test = new char[100];
    if (a) {
        delete[] test; // count 1
        return;
    }
    xxx;
    if (b) {
        delete[] test; // count 2
        return;
    }
    ...
    delete[] test; // count 3
}

使用了ScopeExit

void test () {
    char *test = new char[100];
    std::ofstream ofs("test.txt");
    ScopeExit {
        delete[] test; // 在test函數(shù)生命周期結(jié)束后自動(dòng)執(zhí)行delete[]操作
      ofs.close(); // 在生命周期結(jié)束后自動(dòng)關(guān)閉文件,這里只是舉個(gè)不恰當(dāng)例子,ofstream自動(dòng)生命周期結(jié)束后就會(huì)關(guān)閉
    };
    if (a) {
        return;
    }
    xxx;
    if (b) {
        return;
    }
    ...
}

當(dāng)然,正常C++代碼不鼓勵(lì)使用裸指針,可以使用智能指針來申請(qǐng)資源,這里只是舉個(gè)例子,使用ScopeExit也可以用于處理文件資源的關(guān)閉等等。

兩者代碼比較后優(yōu)劣程度顯而易見,不使用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];
    std::ofstream ofs("test.txt");
    SCOPE_GUARD{
        delete[] test;
        ofs.close();
    };
    if (a) {
        return;
    }
    ...
    if (b) {
        return;
    }
    ...
}

RAII還有很多有趣的妙用,后續(xù)還會(huì)介紹,請(qǐng)持續(xù)關(guān)注。

到此這篇關(guān)于巧妙使用RAII中的ScopeExit的文章就介紹到這了,更多相關(guān)RAII妙用ScopeExit內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論