單例模式(singleton pattern,也稱為單件模式),使用最廣泛的設計模式之一。其意圖是保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點,該例項被所有程式模組共享。
定義乙個單例類,私有化它的建構函式,以防止外界建立單例類的物件;使用類的私有靜態指標變數指向類的唯一例項,並用乙個公有的靜態方法獲取該例項。
教學版,即懶漢版(lazy singleton):單例例項在第一次被使用時才進行初始化,這叫做延遲初始化。
// version 1.0
class singleton;~
singleton()
;singleton
(const singleton&);
singleton& operator=
(const singleton&);
public:
static singleton*
getinstance()
return instance;}}
;// init static member
singleton* singleton:
:instance =
null
;
lazy singleton存在記憶體洩露的問題,這裡有兩種解決方法:
使用智慧型指標
使用靜態的巢狀類物件
對於第二種解決方法,**如下:
// version 1.1
class singleton;~
singleton()
;singleton
(const singleton&);
singleton& operator=
(const singleton&);
private:
class deletor };
static deletor deletor;
public:
static singleton*
getinstance()
return instance;}}
;// init static member
singleton* singleton:
:instance =
null
;
在程式執行結束時,系統會呼叫靜態成員deletor的析構函式,該析構函式會刪除單例的唯一例項。使用這種方法釋放單例物件有以下特徵:
注意version 1.0與version 1.1都不是執行緒安全的,要使其執行緒安全,可以使用雙檢測鎖模式(double-checked locking pattern):
static singleton*
getinstance()
}return instance;
}
在單例類內再定義乙個巢狀類,總是感覺很麻煩,所以《effective c++》(item 04)中的提出另一種更優雅的單例模式實現,使用函式內的 local static 物件。當第一次訪問getinstance()方法時才建立例項:
// version 1.2
class singleton;~
singleton()
;singleton
(const singleton&);
singleton& operator=
(const singleton&);
public:
static singleton&
getinstance()
};
c++0x以後,要求編譯器保證內部靜態變數的執行緒安全性,故c++0x之後該實現是執行緒安全的,c++0x之前仍需加鎖。
餓漢版(eager singleton):指單例例項在程式執行時被立即執行初始化
// version 1.3
class singleton
}// initialize defaultly
singleton singleton:
:instance;
由於在main函式之前初始化,所以沒有執行緒安全的問題。但是潛在問題在於no-local static物件(函式外的static物件)在不同編譯單元中的初始化順序是未定義的。如果在初始化完成之前呼叫 getinstance() 方法會返回乙個未定義的例項。 C 中單例模式
最簡單的單例實現只需要乙個全域性物件 some class the instance some class get instance 這個實現簡單到沒什麼可說,它在絕大多數情況下能正常工作,之所以說是 絕大多數 主要原因是 2 構造的時間點其實是不確定的,c 標準只要求這個物件在第一次被使用前,它的...
C 中的單例模式
c 中的單例模式 靜態成員經典應用 單例模式 在程式執行過程中,可能會希望某些類的例項物件永遠只有乙個 條件1.把建構函式私有化 2.定義乙個私有的靜態成員變數指標,用於指向單例物件 3.提供乙個公共的返回單例物件的靜態成員函式.class rocket return ms rocket stati...
C 中的單例模式
單例模式 物件只能出現一次 1.將建構函式私有化 2.使用乙個公開靜態方法 3.使用乙個 靜態屬性進行判斷當前視窗是否被建立。private regsiterwindow public static regsiterwindow selfwindow null public static regsi...