raii技術被認為是c++中管理資源的最佳方法,進一步引申,使用raii技術也可以實現安全、簡潔的狀態管理,編寫出優雅的異常安全的**。
raii是c++的發明者bjarne stroustrup提出的概念,raii全稱是「resource acquisition is initialization」,直譯過來是「資源獲取即初始化」,也就是說在建構函式中申請分配資源,在析構函式中釋放資源。因為c++的語言機制保證了,當乙個物件建立的時候,自動呼叫建構函式,當物件超出作用域的時候會自動呼叫析構函式。所以,在raii的指導下,我們應該使用類來管理資源,將資源和物件的生命週期繫結。
智慧型指標(std::shared_ptr和std::unique_ptr)即raii最具代表的實現,使用智慧型指標,可以實現自動的記憶體管理,再也不需要擔心忘記delete造成的記憶體洩漏。毫不誇張的來講,有了智慧型指標,**中幾乎不需要再出現delete了。
記憶體只是資源的一種,在這裡我們討論一下更加廣義的資源管理。比如說檔案的開啟與關閉、windows中控制代碼的獲取與釋放等等。按照常規的raii技術需要寫一堆管理它們的類,有的時候顯得比較麻煩。但是如果手動釋放,通常還要考慮各種異常處理,比如說:
void function()
else if(.....)
fclose(f);
......
}
這裡介紹乙個網上實現的我認為比較簡潔的方法,文章在這裡。作者使用了c++11標準中的lambda表示式和std::function相結合的方法,非常簡潔、明了。直接看**吧:
#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)
class scopeguard
; ~scopeguard()
private:
std::functionhandle_exit_scope_;
};int main()
); ......});
......
}system("pause");
return 0;
}
作者為了使用方便,還定義了根據行號來對scopeguard型別物件命名的巨集定義。看到了吧,當scopeguard物件超出作用域,scopeguard的析構函式中會呼叫handle_exit_scope_函式,也就是lambda表示式中的內容,所以在lamabda表示式中填上資源釋放的**即可,多麼簡潔、明了。既不需要為每種資源管理單獨寫對應的管理類,也不需要考慮手動釋放出現各種異常情況下的處理,同時資源的申請和釋放放在一起去寫,永遠不會忘記。
std::mutex mutex_;
void function()
因為,在互斥量lock和unlock之間的**很可能會出現異常,或者有return語句,這樣的話,互斥量就不會正確的unlock,會導致執行緒的死鎖。所以正確的方式是使用std::unique_lock或者std::lock_guard對互斥量進行狀態管理:
std::mutex mutex_;
void function()
在建立std::lock_guard物件的時候,會對std::mutex物件進行lock,當std::lock_guard物件在超出作用域時,會自動std::mutex物件進行解鎖,這樣的話,就不用擔心**異常造成的執行緒死鎖。
通過上面的分析可以看出,raii的核心思想是將資源或者狀態與物件的生命週期繫結,通過c++的語言機制,實現資源和狀態的安全管理。理解和使用raii能使軟體設計更清晰,**更健壯。
1、2、
3、
C 中RAII機制的介紹與簡單例項
今天看陳碩的多執行緒書上提到了c 中raii技術的使用,通過用c11裡面自帶的智慧型指標來完成對資源的控制,但是一直不太清楚具體raii是怎麼樣的,帶著這樣的疑問,特地去看了幾篇部落格,找了乙個簡單的檔案控制代碼開啟關閉raii管理的例項,瞬間就明白了,這裡分享出來。主要從兩個部分,首先是raii技...
C 中的RAII用法
c 中的raii全稱是 resource acquisition is initialization 直譯為 資源獲取就是初始化 但是這翻譯並沒有顯示出這個慣用法的真正內涵。raii的好處在於它提供了一種資源自動管理的方式,當產生異常 回滾等現象時,raii可以正確地釋放掉資源。舉個常見的例子 cp...
C 中的RAII機制
前言 在寫c 設計模式 單例模式的時候,在寫到例項銷毀時,設計的gc類是很巧妙的,而這一巧妙的設計就是根據當物件的生命週期結束時會自動呼叫其析構函式的,而這一巧妙的設計也是有專業的名詞的 raii。那以下將圍繞raii,全面的講解raii的相關知識。什麼是raii?raii是resource acq...