單例模式(C++版)

單例模式最初定義出現在《設計模式》(艾迪生維斯理,1994):“保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。”

單例模式是設計模式中最簡單的形式之一。這一模式的目的是使得類的一個對象成爲系統中的唯一實例。要實現這一點,可以從客戶端對其進行實例化開始。因此需要用一種只允許生成對象類的唯一實例的機制,“阻止”所有想要生成對象的訪問。使用工廠方法來限制實例化過程。這個方法應該是靜態方法(類方法),因爲讓類的實例去生成另一個唯一實例毫無意義。

這裏寫圖片描述

Static uniqueInstance是singleton的唯一實例,static sharedInstance將它返回客戶端。通常,sharedInstance會檢查uniqueInstance是否已經被實例化。如果沒有,它會生成一個實例然後返回uniqueInstance。

對於系統中的某些類來說,只有一個實例很重要。例如一個系統中可以存在多個打印任務,但是只能有一個正在工作的任務;一個系統只能有一個窗口管理器或文件系統;一個系統只能有一個計時工具或ID(序號)生成器。如在Windows中就只能打開一個任務管理器。如果不使用機制對窗口對象進行唯一化,將彈出多個窗口,如果這些窗口顯示的內容完全一致,則是重複對象,浪費內存資源;如果這些窗口顯示的內容不一致,則意味着在某一瞬間系統有多個狀態,與實際不符,也會給用戶帶來誤解,不知道哪一個纔是真實的狀態。因此有時確保系統中某個對象的唯一性即一個類只能有一個實例非常重要。

如何保證一個類只有一個實例並且這個實例易於被訪問呢?定義一個全局變量可以確保對象隨時都可以被訪問,但不能防止我們實例化多個對象。一個更好的解決辦法是讓類自身負責保存它的唯一實例。這個類可以保證沒有其他實例被創建,並且它可以提供一個訪問該實例的方法。這就是單例模式的模式動機。

class Singleton
{
   private:
     Singleton(){}//構造函數是私有的

     static Singleton *m_pInstance;//有一個指向唯一實例的靜態指針m_pInstance

   public:
     static Singleton *GetInstance()
     {
          if(m_pInstance==NULL)
          {
             m_pInstance=new Singleton();
          }
          return m_pInstance;
     }

};

用戶訪問的唯一實例的方法只有GetInstance()成員函數。如果不通過這個函數,任何創建實例的嘗試都將失敗,因爲此時類的構造函數是私有的。GetInstance()使用懶惰初始化,即它的返回值是當這個函數首次被訪問時創建的。

那麼m_pInstance指向的空間什麼時候釋放呢?更嚴重的問題:該實例的析構函數什麼時候執行?

如果在類的析構行爲中有必須的操作,比如關閉文件,釋放外部資源,那麼上面的代碼解決不了這個問題。我們需要一種方法,可以正常刪除該實例。

我們知道,程序在結束的時候,系統會自動析構所有的全局變量。事實上,系統也會析構所有的類的靜態成員變量,就像這些靜態成員也是全局變量一樣。利用這個特徵,我們可以在單例類中定義一個這樣的靜態成員變量。而它的唯一工作就是在析構函數中刪除單例類的實例。

class Singleton
{
   private:
        Singleton(){}//構造函數是私有的
        static Singleton *m_pInstance;
        class Garbo  //唯一目的就是在析構函數中刪除Singleton的實例
        {
             ~Garbo()
             {
                  if(Singleton::m_pInstance)
                  {
                      delete Singleton::m_pInstance;
                  }
             }
        };
        static Garbo _Garbo;//靜態成員變量,程序結束的時候系統會自動調用其析構函數
   publicstatic Singleton *GetInstance()
       {
           if(m_pInstance==NULL)
           {
               m_pInstance=new Singleton();
           }
           return m_pInstance;
       }

};

程序結束時,系統會自動調用Singleton的靜態成員_Garbo的析構函數,該析構函數會刪除單例的唯一實例。

發佈了59 篇原創文章 · 獲贊 138 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章