探索單例模式

2021-10-05 17:43:09 字數 1253 閱讀 7282

意圖:保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。

主要解決:乙個全域性使用的類頻繁地建立與銷毀。

何時使用:當您想控制例項數目,節省系統資源的時候。

如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則建立。

關鍵**:建構函式是私有的。

應用例項:

乙個班級只有乙個班主任。

windows 是多程序多執行緒的,在操作乙個檔案的時候,就不可避免地出現多個程序或執行緒同時操作乙個檔案的現象,所以所有檔案的處理必須通過唯一的例項來進行。

一些裝置管理器常常設計為單例模式,比如乙個電腦有兩台印表機,在輸出的時候就要處理不能兩台印表機列印同乙個檔案。

優點:在記憶體裡只有乙個例項,減少了記憶體的開銷,尤其是頻繁的建立和銷毀例項(比如管理學院首頁頁面快取)。

避免對資源的多重占用(比如寫檔案操作)。

缺點:沒有介面,不能繼承,與單一職責原則衝突,乙個類應該只關心內部邏輯,而不關心外面怎麼樣來例項化。

使用場景:

要求生產唯一序列號。

web 中的計數器,不用每次重新整理都在資料庫裡加一次,用單例先快取起來。

建立的乙個物件需要消耗的資源過多,比如 i/o 與資料庫的連線等。

之前看《程式設計師的自我修養》這本書時發現一段比較細節之處;

volatile t * pinst = nullptr;

t * getinstance()

return pinst;

}

書中指出:

1,分配記憶體

2:,呼叫建構函式

所以 pinst = new t();這句**分為三步:

1,分配記憶體

2,在記憶體的位置上呼叫建構函式

3,將記憶體的位址複製給pinst

在這三步中,2和3的順序是可以顛倒的。也就是說,完全有可能出現pinst的值已經不是nullptr,但物件的仍然沒有構造完畢,這時候如果出現另外乙個對getinstance的併發呼叫,此時第乙個if內的pinst已經不為nullptr。所以這個呼叫會直接返回尚未構造完全的物件的位址以提供給使用者使用。那麼這個程式就存在崩潰的可能性。"

所以在使用單例模式的時候盡量用最推薦的模式 --區域性靜態變數

class singleton

這樣做並不好,理由主要是無法避免使用者使用delete instance導致物件被提前銷毀。還是建議大家使用返回引用的方式。

單例模式 探索之旅

當程式中需要在多處用到乙個類的同乙個例項時,我們通常得給此類宣告乙個全域性變數,不然只有通過函式鏈傳遞此類例項的引用,然而這兩種方式都存在一定問題,特別是要考慮執行緒安全時。我們需要一種更方便安全的方式來應對多處用到乙個類的同乙個例項問題。程式生命週期中,保證類只有乙個例項,且提供乙個訪問它的全域性...

單例模式 單例模式

餓漢式 急切例項化 public class eagersingleton 2.宣告靜態成員變數並賦初始值 類初始化的時候靜態變數就被載入,因此叫做餓漢式 public static eagersingleton eagersingleton new eagersingleton 3.對外暴露公共的...

單例 單例模式

簡單的實現乙個單例 instancetype sharedinstance return instance 真正的單例模式 myclass sharedinstance return instance id allocwithzone nszone zone return nil id copywi...