C 中的RAII用法

2021-07-13 14:31:04 字數 2416 閱讀 9478

c++中的raii全稱是「resource acquisition is initialization」,直譯為「資源獲取就是初始化」。但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常、回滾等現象時,raii可以正確地釋放掉資源。

舉個常見的例子:

[cpp]view plain

copy

void

func()  

... // 如果 在使用fp指標時產生異常 並退出

// 那麼 fp檔案就沒有正常關閉

fclose(fp);  

}  

在資源的獲取到釋放之間,我們往往需要使用資源,但常常一些不可預計的異常是在使用過程中產生,就會使資源的釋放環節沒有得到執行。

此時,就可以讓raii慣用法大顯身手了。

raii的實現原理很簡單,利用stack上的臨時物件生命期是程式自動管理的這一特點,將我們的資源釋放操作封裝在乙個臨時物件中。

具體示例**如下:

[cpp]view plain

copy

class

resource{};  

class

raii //獲取資源

~raii()  

//釋放資源

resource* get()     

//訪問資源

private

:  resource* r_;  

};  

比如檔案操作的例子,我們的raii臨時物件類就可以寫成:

[cpp]view plain

copy

class

fileraii  

~fileraii() //在析構函式中進行檔案關閉

file

* get()   

private

:  file

* file_;  

};  

則上面這個開啟檔案的例子就可以用raii改寫為:

[cpp]view plain

copy

void

func()  

fileraii fileraii(fp);  

... // 如果 在使用fp指標時產生異常 並退出

// 那麼 fileraii在棧展開過程中會被自動釋放,析構函式也就會自動地將fp關閉

// 即使所有**是都正確執行了,也無需手動釋放fp,fileraii它的生命期在此結束時,它的析構函式會自動執行!    

}  

這就是raii的魅力,它免除了對需要謹慎使用資源時而產生的大量維護**。在保證資源正確處理的情況下,還使得**的可讀性也提高了不少。

建立自己的raii類

一般情況下,raii臨時物件不允許複製和賦值,當然更不允許在heap上建立,所以先寫下乙個raii的base類,使子類私有繼承base類來禁用這些操作:

[cpp]view plain

copy

class

raiibase  

~raiibase(){}//由於不能使用該類的指標,定義虛函式是完全沒有必要的

raiibase (const

raiibase &);  

raiibase & operator = (const

raiibase &);  

void

* operator 

new(

size_t

size);   

// 不定義任何成員

};  

當我們要寫自己的raii類時就可以直接繼承該類的實現:

[cpp]view plain

copy

template

<

typename

t>  

class

resourcehandle: 

private

raiibase 

//私有繼承 禁用base的所有繼承操作

//獲取資源

~resourcehandle()  

//釋放資源

t *get()     

//訪問資源

private

:  t * r_;  

};  

將handle類做成模板類,這樣就可以將class型別放入其中。另外, resourcehandle可以根據不同資源型別的釋放形式來定義不同的析構函式。

由於不能使用該類的指標,所以使用虛函式是沒有意義的。

注:自己寫的raii類並沒有經過大量的實踐,可能存在問題,請三思而慎用。這裡只是記錄下自己的實現想法。

C 之RAII慣用法

c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 在資...

C 之RAII慣用法

c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 cp...

C 之RAII慣用法

c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 vo...