C 11資源管理新方法ON SCOPE EXIT

2021-07-24 03:07:07 字數 2173 閱讀 5471

先來看一下背景:在c++98的語言機制中,物件在超出作用域的時候其析構函式會被自動呼叫。接著,bjarne stroustrup在tc++pl裡面定義了raii(resource acquisition is initialization)正規化(即:物件構造的時候其所需的資源便應該在建構函式中初始化,而物件析構的時候則釋放這些資源)。raii意味著我們應該用類來封裝和管理資源,對於記憶體管理而言,boost第乙個實現了工業強度的智慧型指標,如今智慧型指標(shared_ptr和unique_ptr)已經是c++11的一部分,簡單來說有了智慧型指標意味著你的c++**基中幾乎就不應該出現delete了。

對於c++98的記憶體管理,我們可以建立乙個資源管理類,舉個例子:

classa};

void rsrlek()

現在運用資源管理類進行記憶體管理:

class a

};class b

~b()

private:

a* a;

};void nonrsrlek()

/*<------------------函式退出,物件b自動析構,並刪除指標a,避免了記憶體洩露*/

在c++11中引入了智慧型指標(shared_ptr,unique_ptr等),現在可以這樣寫**:

#include 

using

namespace

std;

class a

};void nonrsrlek()

/*<----------函式退出,a自動釋放記憶體*/

智慧型指標shared_ptr< a >相當於資源管理類b,但就如《more effective c++》一書中所說,智慧型指標並不是普通指標;在《c++ primer(第五版)》中也提過,不能將普通指標和智慧型指標不能混用,否則會出現懸掛指標現象。

現在引入一種新處理方法:

classa};

void nonrsrlek()

//lambda可呼叫物件

);//do something

} /*<----------函式退出,a通過on_scope_exit釋放記憶體*/

而on_scope_exit實際上類似於乙個資源管理類,其實現如下:

#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

on_scope_exit是scopeguard ***(callback)的巨集定義,而為了為scopeguard 物件起不重複的名字,這裡用了scopeguard_linename 這個巨集實現把行號混入變數名***,實際上scopeguard 這個類才是類資源管理的類,其實現如下:

class scopeguard

~scopeguard()

void dismiss()

private:

std::function onexitscope_;

bool dismissed_;

private: // noncopyable /*《effencient c++》中有接收,防止複製*/

scopeguard(scopeguard const&);

scopeguard& operator=(scopeguard const&);

};

這個類的使用很簡單,你交給它乙個std::function,它負責在析構的時候執行,絕大多數時候這個function就是lambda。

當然,它處理實現資源管理外,用法還很靈活,例如:

handle h = createfile(...);

scopeguard onexit([&] );

在**塊內開啟乙個檔案,然後直接呼叫scopeguard 或者呼叫on_scope_exit巨集,實現在**塊退出時自動呼叫closehandle()完成所需要的工作(並不一定是釋放指標);

C 為列舉建立新方法

可以使用擴充套件方法新增特定於某個特定列舉型別的功能。示例 在下面的示例中,grades 列舉表示學生可能在班裡收到的字母等級分。該示例將乙個名為 passing 的擴充套件方法新增到 grades 型別中,以便該型別的每個例項現在都 知道 它是否表示合格的等級分。using system usin...

C 資源管理之 RAII

raii,它是 r esource acquisition is initialization 的首字母縮寫。也稱為 資源獲取就是初始化 是c 等程式語言常用的管理資源 避免記憶體洩露的方法。它保證在任何情況下,使用物件時先構造物件,最後析構物件。raii的好處在於它提供了一種資源自動管理的方式,當...

C 函式傳參的新方法 引用

關於傳參方式,之前在c語言裡面已經接觸過了兩種 傳值呼叫和傳址呼叫兩種。而作為c語言的加強版,c 中自然也是將這兩種方式,繼承了下來,並且在c 裡面也有了新的一種傳參方式 引用。首先,從概念上講,所謂的引用,就是給乙個已經存在的變數,起了乙個新的別名。其實它用的還是和被引用的物件是同一塊記憶體空間,...