[轉載] c++ RAII 機制

前言:

今天看到這個名詞 RAII 我還沒有見過 就看了一下

定義:

RAII技術被認爲是C++中管理資源的最佳方法,進一步引申,使用RAII技術也可以實現安全、簡潔的狀態管理,編寫出優雅的異常安全的代碼。

資源管理
RAII是C++的發明者Bjarne Stroustrup提出的概念,RAII全稱是“Resource Acquisition is Initialization”,直譯過來是“資源獲取即初始化”,也就是說在構造函數中申請分配資源,在析構函數中釋放資源。因爲C++的語言機制保證了,當一個對象創建的時候,自動調用構造函數,當對象超出作用域的時候會自動調用析構函數。所以,在RAII的指導下,我們應該使用類來管理資源,將資源和對象的生命週期綁定。

看個例子:

void Func()
{
  FILE *fp;
  char* filename = "test.txt";
  if((fp=fopen(filename,"r"))==NULL)
  {
      printf("not open");
      exit(0);
  }
  ... // 如果 在使用fp指針時產生異常 並退出
       // 那麼 fp文件就沒有正常關閉
	
  fclose(fp);
}

如果 出現了異常 return了 那麼fp 就沒法析構了 內存泄露了

RAII 就是來解決這樣的問題了
析構 臨時棧上面的對象

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

class FileRAII{
public:
    FileRAII(FILE* aFile):file_(aFile){}
    ~FileRAII() { fclose(file_); }//在析構函數中進行文件關閉
    FILE* get() {return file_;}
private:
    FILE* file_;
};

上面的代碼可以改爲

void Func()
{
  FILE *fp;
  char* filename = "test.txt";
  if((fp=fopen(filename,"r"))==NULL)
  {
      printf("not open");
      exit(0);
  }
  FileRAII fileRAII(fp);

 }

如果 在使用fp指針時產生異常 並退出
那麼 fileRAII在棧展開過程中會被自動釋放,析構函數也就會自動地將fp關閉

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

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

創建自己的RAII類

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

class RAIIBase  
{  
protected:  
    RAIIBase(){}  
    ~RAIIBase(){}//由於不能使用該類的指針,定義虛函數是完全沒有必要的  
private:      
    RAIIBase (const RAIIBase &);  
    RAIIBase & operator = (const RAIIBase &);  
    void * operator new(size_t size);   
    // 不定義任何成員  
};  
 
 
template<typename T>  
class ResourceHandle: public RAIIBase //私有繼承 禁用Base的所有繼承操作  
{  
public:  
    explicit ResourceHandle(T * aResource):r_(aResource){}//獲取資源  
    ~ResourceHandle() {delete r_;} //釋放資源  
    T *get()    {return r_ ;} //訪問資源  
private:  
    T * r_;  
};

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

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

一個demo 正好用的就是這個RAII 思想

c++ 11 std::lock_guard

轉載 :https://blog.csdn.net/hunter8777/article/details/6327704

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章