轉至:http://www.cppblog.com/ElliottZC/archive/2007/07/20/28421.html
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
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(){}
static Singleton* Instance()
if(!m_pInstance.get())
m_pInstance = std::auto_ptr<Singleton>(new Singleton());
}
return m_pInstance.get();
}
};
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);
DEFINE_SINGLETON(YY);
public:
//your interfaces here...
};
在cpp文件中,書寫:
IMPLEMENT_SINGLETON(YY);
如果需要定義其他的單件類,重複上面的定義,就可以了。