程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 單實例設計模式的實現

單實例設計模式的實現

編輯:關於C++

單實例設計可能是使用最廣泛的設計模式。其思想意圖是保證一個類只有一個實例,並且提供類對象的全程訪問。單實例對象應用的范圍很廣:如GUI應用必須是單鼠標,MODEM的聯接需要一條且只需要一條電話線,操作系統只能有一個窗口管理器,一台PC連一個鍵盤。本文將討論如何用C++實現單實例模式,並解釋如何優化單線程應用的設計。

設計方案

使用全程對象能夠保證方便地訪問實例,但是不能保證只聲明一個對象-也就是說除了一個全程實例外,仍然能創建相同類的本地實例。單實例模式通過類本身來管理其唯一實例,這種特性提供了問題的解決辦法。唯一的實例是類的一個普通對象,但設計這個類時,讓它只能創建一個實例並提供對此實例的全程訪問。唯一實例類Singleton在靜態成員函數中隱藏創建實例的操作。習慣上把這個成員函數叫做Instance(),它的返回值是唯一實例的指針。Singleton的定義如下:

class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private:
static Singleton* pinstance;
};

你還可以創建諸如Mouse,FileManager,Scheduler等為名字的類並聲明相應的成員。為了保證用戶不能創建類的本地實例,Singleton的構造器是賦值操作符,構造函數的副本被聲明為protected。類中還聲明了一個私有的靜態實例指針。當第一次調用靜態函數Instance()時,它創建唯一實例,將實例地址賦值給pinstance,然後返回這個地址。在每次並發調用中,Instance()也將只返回這個地址。

下面是類的實現:

Singleton* Singleton::pinstance = 0;// 初始化指針
Singleton* Singleton::Instance ()
{
if (pinstance == 0) // 是第一次調用嗎?
{
pinstance = new Singleton; // 創建唯一實例
}
return pinstance; // 唯一實例的地址
}
Singleton::Singleton()
{
//... 實現必要的實例初始化
}

用戶訪問唯一實例的方法只有Instance()成員函數。如果不通過這個函數,任何創建實例的嘗試都將失敗,因為類的構造函數是被保護的。Instance()使用懶惰初始化,也就是說它返回的值是當這個函數被首次訪問時被創建的。這是一種防彈設計-所有Instance()之後的調用都返回相同實例的指針:

Singleton *p1 = Singleton::Instance();
Singleton *p2 = p1->Instance();
Singleton & ref = * Singleton::Instance();

雖然本文的例子針對的是單實例,但對Instance()稍加修改,這個設計模板便可適用於可變多實例情況。如一個類允許最多五個實例。

優化Singleton類,使之適用於單線程應用

Singleton使用操作符new為唯一實例分配存儲空間。因為new操作符是線程安全的,在多線程應用中你可以使用此設計模板。但是有一個缺陷:就是在應用程序終止之前必須手工用delete摧毀實例。否則,不僅導致內存溢出,還要造成不可預測的行為,因為Singleton的析構函數將根本不會被調用。而通過使用本地靜態實例代替動態實例,單線程應用可以很容易避免這個問題。以下是與上面的Instance()稍有不同的實現,這個實現專門用於單線程應用:

Singleton* Singleton::Instance ()
{
static Singleton inst;
return &inst;
}

本地靜態對象實例inst是第一次調用Instance()時被構造,一直保持活動狀態直到應用程序終止。指針pinstance變得多余並可以從類定義中刪除掉。與動態分配對象不同,靜態對象當應用程序終止時被自動銷毀掉,所以就不必再手動銷毀實例了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved