C 設計模式之單例模式

2022-02-23 17:32:22 字數 3031 閱讀 9427

單例模式:

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

應用場景:

在軟體系統中,經常有這樣一些特殊的類,必須保證它們在系統中只存在乙個例項,才能確保它們的邏輯正確性。

乙個全域性使用的類頻繁地建立與銷毀。

比如:windows 資源管理器,**站等。

這應該是類設計者的職責,而不是使用者的職責。也就是說這個單例不應該由人來控制,而應該由**來限制,強制單例。

5 mutex mu;//執行緒互斥物件

6 classsingleton

11 private:

12 //私有建構函式,不允許使用者自己生成物件

13 singleton()

14

17 singleton(const singleton&other);

18 static singleton* m_instance; //靜態成員變數

19 };

單例模式分為兩種型別:餓漢式,懶漢式。

餓漢式:

1 // 餓漢式

2 singleton*singleton::getinstance()

3 6 // 靜態成員需要先初始化

7 singleton* singleton::m_instance = new singleton();

在訪問量比較大,或者可能訪問的執行緒比較多時,可以實現更好的效能,以空間換時間。

因為是靜態屬性在單例類定義的時候就進行例項化,所以優點是執行緒是安全的,缺點是無論使用者是否使用單例物件都會建立單例物件。

懶漢式:

1 //靜態成員需要先初始化

2 singleton* singleton::m_instance =null;

3 // 懶漢式

4 singleton*singleton::getinstance()

5

在第一次呼叫getinstance()的時候例項化,不呼叫就不會生成物件,不佔據記憶體。適合在訪問量較小時,以時間換空間。

懶漢式是執行緒不安全的,比如兩個執行緒同時執行到上面的第7行後,那麼兩個將分別建立兩個例項,不滿足單例的要求。

為解決執行緒不安全,有了下面的加鎖處理:

1 // 懶漢式  加鎖(代價高)

2 singleton*singleton::getinstance()

3

但因為每次呼叫該方法時都要進行加鎖,代價太高,因而出現了著名的雙檢查鎖:

1 //   懶漢式 雙檢查鎖

2 singleton*singleton::getinstance()

3 11 returnm_instance;

12 }

近乎完美。

但,由於編譯器等進行優化,導致記憶體讀寫存在reorder,有時導致雙檢查鎖的不安全性,處理辦法:

1 //c++ 11版本之後的跨平台實現 

2 // atomic c++11中提供的原子操作

3 #include 4 #include 5

6 classsingleton

11 private:

12 //私有建構函式,不允許使用者自己生成物件

13 singleton()

14 singleton(const singleton&other);

15 static atomicm_instance; //靜態成員變數

16 staticmutex m_mutex;

17 };

18 std::atomicsingleton::m_instance;

19 std::mutex singleton::m_mutex;

20 /*

21 * std::atomic_thread_fence(std::memory_order_acquire);

22 * std::atomic_thread_fence(std::memory_order_release);

23 * 這兩句話可以保證他們之間的語句不會發生亂序執行。

24 */

25 singleton*singleton::getinstance()

36 }

37 returntmp;

38 }

最後是main方法

1 voidtest01()

2 8

9 voidtest02()

10 14

15 16 // 多執行緒呼叫

17 voidthread01()

18 25 }

26 voidthread02()

27 34 }

35 36 intmain()

37 51

52 system("pause");

53 return 0;

54 }

優點: 

在系統記憶體中只存在乙個物件,因此可以節約系統的資源,對於一些需要頻繁建立和銷毀的物件,使用單例模式無疑是提高了系統的效能;

單例模式允許可變數目的例項。基於單例模式可以進行擴充套件,使用與控制單例物件相似的方法獲得指定個數的例項物件,既節約了系統資源,又解決了由於單例物件共享過多有損效能的問題(自行提供指定數目例項物件的類可成為多例類) 。

缺點:由於單例模式沒有抽象層,所以擴充套件起來很難;

單例類職責過重,在一定程度上違背了單一職責原則。因為單例類既提供了業務方法,又提供了建立物件的方法(工廠方法),將物件的建立和物件本身的功能耦合在一起;

不適用於變化的物件,如果同一型別的物件總是要在不同的用例場景發生變化,單例就會引起資料的錯誤,不能儲存彼此的狀態;

多執行緒模式下較複雜。

C 設計模式之單例模式

在遊戲開發過程中,我們時常會遇到單例模式的運用場景。比如你遊戲當中的最終boss,你希望你的boss只能有乙個,所以這裡你就可以用單例模式 那麼什麼是單例模式呢?看下面的 分析。include include using namespace std class singleton public st...

C 設計模式之單例模式

設計模式是以理論的高度,總結了開發過程中的一多種不同的方法,在各種設計模式中,它們都有著不同實現方式,所起的作用也不相同,我最近看了部分設計模式,主要是以我自己的理解來闡述對它們的看法。我們可以看到單例的大概實現是很簡單的。幾個需要注意的地方是 只有當我們的建構函式為私有時,此時,我們在類外部就不能...

C 設計模式之 單例模式

單例模式,故名思義,其意圖是保證乙個類只有乙個例項,並提供乙個訪問它的全域性訪問點,該例項被所有的程式模組共享.在很多地方要用到這種設計模式,如系統的日誌輸出,作業系統的視窗,乙個pc連乙個鍵盤等.單例模式有許多實現方法.第一次呼叫該類例項的時候才產生乙個新的該類例項,並在以後僅返回此例項,需要加鎖...