一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - 巧妙使用RAII中的ScopeExit

巧妙使用RAII中的ScopeExit

2021-11-04 13:34程序喵大人 C/C++

Resource Acquisition Is Initialization,資源獲取即初始化,將資源的生命周期與一個對象的生命周期綁定,這篇文章主要介紹了巧妙使用RAII中的ScopeExit,需要的朋友可以參考下

什么是RAII

Resource Acquisition Is Initialization,資源獲取即初始化,將資源的生命周期與一個對象的生命周期綁定,舉例來說就是,把一些資源封裝在類中,在構造函數請求資源,在析構函數中釋放資源且絕不拋出異常,而一個對象在生命周期結束時會自動調用析構函數,即資源的生命周期與一個對象的生命周期綁定。

RAII的應用

見如下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
std::mutex mutex;
void func() {}
void NoRAII() {
    mutex.lock();
    func();
    if (xxx) {
        mutex.unlock();// 多次需要調用unlock(),還有可能忘記調用unlock導致一直持有鎖
        return;
    }
    ...
    mutex.unlock();
}
void RAII() { // 不需要顯式調用unlock
    std::lock_guard<std::mutex> lock(mutex);
    func();
    if (xxx) {
        return;
    }
    ...
    return;
}

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

RAII的巧用

最近研究了boost中的ScopeExit,發現這是個很高級的特性,利用RAII特性,可以在作用域結束時自動關閉已經打開的資源或做某些清理操作,類似于unique_ptr,但又比unique_ptr方便,不需要自定義delete函數。
舉例: 如果沒有ScopeExit

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void test () {
    char *test = new char[100];
    std::ofstream ofs("test.txt");
    ScopeExit {
        delete[] test; // 在test函數生命周期結束后自動執行delete[]操作
      ofs.close(); // 在生命周期結束后自動關閉文件,這里只是舉個不恰當例子,ofstream自動生命周期結束后就會關閉
    };
    if (a) {
        return;
    }
    xxx;
    if (b) {
        return;
    }
    ...
}

當然,正常C++代碼不鼓勵使用裸指針,可以使用智能指針來申請資源,這里只是舉個例子,使用ScopeExit也可以用于處理文件資源的關閉等等。

兩者代碼比較后優劣程度顯而易見,不使用ScopeExit需要在return前多次做資源清理操作,而使用了ScopeExit則只需做一次聲明后在作用域結束后會自動進行相關的資源清理操作,方便而且不易出錯。

ScopeExit實現

這里參考boost使用C++11實現了一套ScopeExit機制

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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__)

使用方式如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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還有很多有趣的妙用,后續還會介紹,請持續關注。

到此這篇關于巧妙使用RAII中的ScopeExit的文章就介紹到這了,更多相關RAII妙用ScopeExit內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://mp.weixin.qq.com/s

延伸 · 閱讀

精彩推薦
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
主站蜘蛛池模板: 亚州一区二区 | 日本xxxⅹ69xxxx护士 | 好大用力深一点女公交车 | 精品国产免费第一区二区 | 爱情岛论坛亚洲品质自拍视频 | 欧美添下面视频免费观看 | 国产成人福利色视频 | 日韩精品特黄毛片免费看 | 美女的隐私视频免费看软件 | 精品国语国产在线对白 | 国产精品久久久久久搜索 | 午夜宅男网 | 欧美日韩亚洲区久久综合 | 国产视频一区二 | 91混血大战上海双胞胎 | 啪一啪日一日 | 国产成+人+亚洲+欧美综合 | 国产99re在线观看69热 | 2022国产麻豆剧传媒古装 | 亚洲第一区欧美日韩精品 | 小早川怜子视频在线观看 | 性奶老妇 视频 | 亚洲视频999| 久久免费看少妇级毛片蜜臀 | 天天久久综合网站 | 99午夜 | 蘑菇香蕉茄子绿巨人丝瓜草莓 | 成人精品一区二区三区 | 国产九九 | 欧美伊人久久久久久久久影院 | 青青草精品在线观看 | 日韩毛片基地一区二区三区 | 日韩在线二区全免费 | 午夜神器18以下不能进免费 | 天堂成人影院 | 国产大神91一区二区三区 | 免费 视频| 国产精品一区二区三区免费 | 日韩精品一区二区三区老鸭窝 | 国产一区二区三区四 | 国产欧美日韩综合二区三区 |