c++單件實例模式的實現 及其多個單件子類

轉至:http://www.cppblog.com/ElliottZC/archive/2007/07/20/28421.html

 

1. 意圖
      保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
2. 動機
      對一些類來說,只有一個實例是很重要的。雖然系統中可以有許多打印機,但卻只應該有一個打印假脫機( printer spooler),只應該有一個文件系統和一個窗口管理器。一個數字濾波器只能有一個A / D轉換器。一個會計系統只能專用於一個公司。
      我 們怎麼樣才能保證一個類只有一個實例並且這個實例易於被訪問呢?一個全局變量使得一個對象可以被訪問,但它不能防止你實例化多個對象。一個更好的辦法是, 讓類自身負責保存它的唯一實例。這個類可以保證沒有其他實例可以被創建(通過截取創建新對象的請求),並且它可以提供一個訪問該實例的方法。這就是 Singleton模式。
3. 適用性
      在下面的情況下可以使用Singleton模式. 當類只能有一個實例而且客戶可以從一個衆所周知的訪問點訪問它時。 當這個唯一實例應該是通過子類化可擴展的,並且客戶應該無需更改代碼就能使用一個擴展的實例時。
4. 結構
5. 參與者
      Singleton
      定義一個GetInstance操作,允許客戶訪問它的唯一實例。GetInstance是一個類操作(即Smalltalk中的一個類方法和C++中的一個靜態成員函數)。可能負責創建它自己的唯一實例。
6. 協作
      客戶只能通過Singleton的GetInstance操作訪問一個Singleton的實例。
7. 效果
      Singleton模式有許多優點:
      1) 對唯一實例的受控訪問因爲Singleton類封裝它的唯一實例,所以它可以嚴格的控制客戶怎樣以及何時訪問它。
      2) 縮小名空間Singleton模式是對全局變量的一種改進。它避免了那些存儲唯一實例的全局變量污染名空間。
      3) 允許對操作和表示的精化Singleton類可以有子類,而且用這個擴展類的實例來配置一個應用是很容易的。你可以用你所需要的類的實例在運行時刻配置應用。
      4) 允許可變數目的實例這個模式使得你易於改變你的想法,並允許Singleton類的多個實例。此外,你可以用相同的方法來控制應用所使用的實例的數目。只有允許訪問Singleton實例的操作需要改變。
      5) 比類操作更靈活另一種封裝單件功能的方式是使用類操作(即C++中的靜態成員函數或者是Smalltalk中的類方法)。但這兩種語言技術都難以改變設計以允許一個類有多個實例。
      此外,C++中的靜態成員函數不是虛函數,因此子類不能多態的重定義它們。
8. 實現
class Singleton
{
      static std::auto_ptr<Singleton> m_pInstance;
protected:
      //prevent user making our any instance by manually
      //構造函數是保護類型的。
      Singleton(){}
public:
      ~Singleton(){}
      //Return this singleton class' instance pointer
      static Singleton* Instance()
      {
            if(!m_pInstance.get())
            {
                   m_pInstance = std::auto_ptr<Singleton>(new Singleton());
            }
            return m_pInstance.get();
      }
 };
      怎樣來使用它呢?不要試圖從這個類派生你的單件子類,那樣的結果是不妥當的,如果你需要多個單件子類,還是使用下面的宏定義更爲妥當:
#define DEFINE_SINGLETON(cls)/
 private:/
      static std::auto_ptr<cls> m_pInstance;/
 protected:/
      cls(){}/
 public:/
      ~cls(){}/
      static cls* Instance(){/
      if(!m_pInstance.get()){/
      m_pInstance = std::auto_ptr<cls>(new cls());/
      }/
      return m_pInstance.get();/
 }
#define IMPLEMENT_SINGLETON(cls) /
std::auto_ptr<cls> cls::m_pInstance(NULL);
假定你需要實現一個單件類YY,這樣書寫:
class YY
{
    DEFINE_SINGLETON(YY);
public:
    //your interfaces here...
};
在cpp文件中,書寫:
IMPLEMENT_SINGLETON(YY);
需要引入這個類的實例的時候,使用這樣的語句:
YY* pYY = YY::Instance();
這,就是全部。
如果需要定義其他的單件類,重複上面的定義,就可以了。
      當想集中管理一個應用程序所需的所有配置時,可以聲明一個CToolsOptions的類,其中包含配置屬性集合。對於這個類的實例,顯然是一個實例就夠 了;當編寫繪圖程序時,考慮繪製矩形,圓形等分別使用CGraphTool派生的工具類,每個派生類負責處理具體的繪製動作和相關的UI相應邏輯。這些工 具類典型的在被用戶選擇工具欄的圖元按鈕時被選中。依照這種模式,你應該對所有的圖元工具從事註冊工作,使得繪圖程序瞭解運行時刻可以使用那些圖元工具。 同樣的,負責管理註冊信息的這個管理器也只需要一個實例就行了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章