1. 程式人生 > 程式設計 >c++中的單例類模板的實現方法詳解

c++中的單例類模板的實現方法詳解

1、什麼是單例模式

  在架構設計時,某些類在整個系統生命週期中最多隻能有一個物件存在 ( Single Instance )。如超市收銀系統,其外觀主要由顯示器(1個)、掃描槍(1個)、收款箱(1個)組成,在系統正常執行期間這三部分都是唯一存在的;也就是說,顯示器、掃描槍、收款箱這三部分都應該有各自的類,並且每個類只能唯一地例項化一個物件,基於這種模式的程式設計,稱為單例模式。

  !!!單例模式只能建立一個物件,且該物件的生命週期伴隨系統的整個執行期間。

2、怎麼實現單例模式

  思考:如何定義一個類,使得這個類最多隻能建立一個物件?

  分析:因為物件是由建構函式建立的,所以我們應該將問題鎖定在建構函式上;又因為只能建立一個物件,這就意味著只能呼叫一次建構函式;顯然將建構函式的訪問許可權設定為 public 不合適,所以,建構函式的訪問許可權只能是 private。然後,定義一個私有的靜態成員 c_instance = NULL 和 公有的靜態成員函式,通過 c_instance 來判斷是否建立物件。(這個為什麼要使用 靜態成員呢?因為建構函式是私有的,在類的外部無法建立物件,只能通過類名呼叫靜態成員,而靜態成員函式只能呼叫靜態成員變數)

  上述分析過程可簡化為:

  (1)將建構函式的訪問屬性設定為 private;

  (2)定義私有的靜態成員屬性 instance 並初始化為 NULL;

  (3)當需要使用物件時,訪問 instance 的值;

1)空值:建立物件,並用 instance 標記;

2)非空值:返回 instance 標記的物件;

單例模式實現

#include <iostream>
#include <string>

using namespace std;

class SObject
{
  static SObject* c_instance; // 定義識別符號指標;

  /* 不需用拷貝和賦值,在單例模式中,始終只有一個物件 */  
  SObject(const SObject&);
  SObject& operator= (const SObject&);
  
  SObject() // 私有的建構函式
  {
  }
public:
  static SObject* GetInstance();  // 建立物件的入口
  
  void print()
  {
    cout << "this = " << this << endl;
  }
};

SObject* SObject::c_instance = NULL; // 靜態成員類內宣告,類外定義

SObject* SObject::GetInstance() // 單例模式的關鍵
{
  if( c_instance == NULL )
  {
    c_instance = new SObject();
  }
  
  return c_instance;
}

int main()
{
  SObject* s = SObject::GetInstance();
  SObject* s1 = SObject::GetInstance();
  SObject* s2 = SObject::GetInstance();
  
  s->print();  // this = 0x940a008
  s1->print(); // this = 0x940a008
  s2->print(); // this = 0x940a008
  
  return 0;
}
// 注:單例模式中,物件的生命週期存在整個系統執行過程中,所以是絕對不釋放的;

·  其實,在上述的單例模式實現案列中,有一部分程式碼(分析過程中第2、3步)與類本身沒有任何關係,既然是這樣,我們就把這部分單獨提取出來處理。

  問題所在:需要使用單例模式時,必須在每個類中定義 靜態成員變數 c_instance 和 靜態成員函式 GetInstance();當有多個類都需要使用單例模式時,這樣的實現方式明顯的很冗餘,為了能夠程式碼複用,我們可以 將這兩部分抽象成一個新類(做成類模板,宣告為其它類的友元類,這樣與之前的效果一樣)。

基於類模板的單例模式實現

 // 對上個單例模式實現程式碼的改進

// singleton.hpp 單例模式程式碼
#ifndef SINGLETON_H
#define SINGLETON_H

template
< typename T >
class Singleton
{
  static T* c_instance;
public:
  static T* GetInstance();
};

template
< typename T >
T* Singleton<T>::c_instance = NULL;

template
< typename T >
T* Singleton<T>::GetInstance()
{
  if( c_instance == NULL )
  {
    c_instance = new T();
  }
  
  return c_instance;
}

#endif

// main.cpp 測試檔案
#include <iostream>
#include <string>
#include "singleton.hpp"

using namespace std;

class SObject
{
  friend class Singleton<SObject>;  // 當前類需要使用單例模式
  
  SObject(const SObject&);
  SObject& operator= (const SObject&);
  
  SObject()
  {
  }
public:
  
  void print()
  {
    cout << "this = " << this << endl;
  }
};

int main()
{
  SObject* s = Singleton<SObject>::GetInstance();
  SObject* s1 = Singleton<SObject>::GetInstance();
  SObject* s2 = Singleton<SObject>::GetInstance();
  
  s->print();  // 0xe63c20
  s1->print(); // 0xe63c20
  s2->print(); // 0xe63c20
  
  return 0;
}

  在今後工作中,如果一個類(SObject)要使用單例模式(Singleton 單例模式的類模板),只需三步驟:

  (1)類(SObject)的建構函式必須私有化;同時,拷貝建構函式、過載=操作符 也私有化;

  (2)將單例模式的類模板宣告為這個類的友元類; friend class Singleton<SObject>;

  (3)通過 單例模式類模板中 SObject* s = Singleton<SObject>::GetInstance(); 建立物件。

到此這篇關於c++中的單例類模板的實現方法詳解的文章就介紹到這了,更多相關c++ 單例類模板內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!