天天看點

從唯一執行個體談靜态成員

在實際的項目中我們可能需要這樣一種類,它的對象在整個項目中隻能有一個,在整個程式中隻能建立一個類的對象,比如說,最常用的mp3播放軟體Winamp,由于它需要獨占計算機中的音頻裝置,是以該程式隻允許自身運作唯一的一個例程。

c++并沒有提供這一特性,我們可以自己封裝一個唯一執行個體的類,為了完成這個工作,我們需要一個靜态的整型資料成員用于記錄目前程式中類的執行個體個數,還需要一個指向自身的靜态指針,指向新建立的類的對象。實作的代碼如下:

class CSingle  
{
private:
  CSingle(){};
  CSingle(CSingle &r){};
  void operator = (CSingle &r){}; 
  ~CSingle(){};

public:
  static CSingle* Create();
  static void Release();

private:
  static int m_nCount;
  static CSingle *m_pInstance;
};      
int CSingle::m_nCount = 0;
CSingle *CSingle::m_pInstance = NULL;

CSingle* CSingle::Create()
{
  if (0 == m_nCount)
  {
    m_nCount++;
    m_pInstance = new CSingle;
  }else
  {
    return NULL;
  }

  return m_pInstance;
}

void CSingle::Release()
{
  if (0 != m_nCount)
  {
    delete m_pInstance;
    m_nCount--;
  }

  return;
}      

利用一下代碼測試:

CSingle *pObj = CSingle::Create();

  CSingle *pObj1 = CSingle::Create();

  cout<
  cout<

  CSingle::Release();

      

上述代碼使用的是類的靜态成員,靜态成員用static關鍵字進行說明,類的靜态成員可以是靜态資料成員,也可以是靜态函數成員,下面分别來說明這兩個内容:

類的成員函數:我們知道一般程式用來存儲變量的記憶體分為靜态存儲區,和堆棧段,靜态存儲區用于存儲靜态變量和全局變量,而堆棧段用來存儲函數中定義的局部變量,也就是說靜态變量和全局變量在同一段記憶體空間中,也可以相當于一個全局變量,關鍵字static除了在定義靜态變量的時候使用外,還可以作為限定符,限定定義的變量隻能在某一區域内可見,在函數中定義的隻在該函數中可見,在檔案中定義的隻在該檔案中可見。是以說靜态變量是一種限定了可見區域的全局變量,在類中定義的靜态資料變量被限定隻在類中可見,與類的普通成員間最大的差別在于普通成員隻有在類存在時才會在記憶體中真正存在,而靜态成員一旦定義就已經存在,且在整個記憶體中隻有一份,這也就是說所有類共享這一個靜态變量,任何一個類修改了變量的值,都會影響到其他類。因為它們有類的生命周期無關,是以不論類是否建立了對象,都可以使用它們,隻是需要加上類域,因為static已經限定了它們隻在類中可見。

類的成員函數:靜态函數成員與靜态資料成員類似,也是相當于一個全局函數,所有類公用一份,它與類函數的不同在于,普通的類函數都會由編譯器隐式的傳入一個this 指針,而靜态成員沒有傳入這樣一個值,也就意味着這個函數并不知道是哪個類的對象在調用它,自然也就不知道該如何使用哪個類對象的普通成員,是以說c++規定靜态函數成員不能通路非靜态資料成員,而靜态資料成員,所有類共享,是以隻能通路靜态資料成員。靜态函數成員也受類的保護限制,即不能通過對象打點調用對象的私有成員。

繼續閱讀