effective c++:資源管理相關

以對象管理資源

許多資源被動態分配與heap內而後被用於單一區塊或函數內。他們應該在控制流離開那個區開或函數時被釋放。

class Investment{...};						//投資類型繼承體系中的root class
Investment* createInvestment();    				//返回指針,指向Investment繼承體系內的動態分配對象,調用者有責任刪除它
void f(){
  std::shared_ptr<Investment> pInv(createInvestment());	//調用factory函數
   ...                  					//經由shared_ptr的析構函數自動刪除pInv
}

獲得資源後立刻放進管理對象內。以對象管理資源的觀念常被稱爲資源獲取時機便是初始化時機(Resource Acquisition Is Initialization;RAII)

管理對象運用析構函數確保資源被釋放。


然而並非所有資源都是heap-based,對那種資源而言,像auto_ptr和shared_ptr這樣的智能指針往往不適合作爲資源管理者。

假如我們使用C API函數處理類型爲Mutex的互斥對象,共有lock和unlock兩函數可有:

void lock(Mutex* pm);					//鎖定pm所指互斥器
void unlock(Mutex* pm);					//將互斥器解除鎖定

建立一個class用來管理機鎖,這樣的class基本結構由RAII守則支配,也就是”資源在構造期間獲得,在析構期間釋放”:

class Lock{
  public:
  explicit Lock(Mutex* pm):mutexPtr(pm)
  {lock(pm);}   						//獲得資源
  ~Lock(){unlock(mutexPtr);}					//釋放資源
  private:
  Mutex* mutexPtr;
};

客戶對Lock的用法符合RAII方式:

Mutex m;					//定義你需要的互斥器
...
{						//建立一個區塊定義critical section
  Lock m1(&m);			        //鎖定互斥器
  ...						//執行critical section內的操作
}						//在區塊末尾,自動解除互斥器鎖定

Lock ml1(&m);					//鎖定m
Lock ml2(ml1);					//將ml1複製到ml2身上,會發生什麼?

面對“一個RAII對象被複制會發生什麼?”大多數時候會有兩種選擇:

1)禁止複製

class Uncopyable{
protected:					//允許derived對象構造和析構
  Uncopyable(){}
  ~Uncopyable(){}
private:					//不予實現
  Uncopyable(const Uncopyable&);		//阻止copying
  Uncopyable& operator=(const Uncopyable&);
};
class Lock:private Uncopyable{
public:
  ...						//如前
}

2)對底層資源基礎“引用計數法”

tr1::shared_ptr允許指定所謂的“刪除器”,那是一個函數或函數對象,當引用次數爲0時便被調用。

class Lock{
public:
  explicit Lock(Mutex* pm)
    : mutexPtr(pm,unlock)					//以unlock函數作爲刪除器
{
  lock(mutexPtr.get());
}
private:
  std::tr1::shared_ptr<Mutex>mutexPtr;
};






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