單例模式:
保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。
應用場景:
在軟體系統中,經常有這樣一些特殊的類,必須保證它們在系統中只存在乙個例項,才能確保它們的邏輯正確性。
乙個全域性使用的類頻繁地建立與銷毀。
比如: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 //靜態成員需要先初始化在第一次呼叫getinstance()的時候例項化,不呼叫就不會生成物件,不佔據記憶體。適合在訪問量較小時,以時間換空間。2 singleton* singleton::m_instance =null;
3 // 懶漢式
4 singleton*singleton::getinstance()
5
懶漢式是執行緒不安全的,比如兩個執行緒同時執行到上面的第7行後,那麼兩個將分別建立兩個例項,不滿足單例的要求。
為解決執行緒不安全,有了下面的加鎖處理:
1 // 懶漢式 加鎖(代價高)但因為每次呼叫該方法時都要進行加鎖,代價太高,因而出現了著名的雙檢查鎖:2 singleton*singleton::getinstance()
3
1 // 懶漢式 雙檢查鎖近乎完美。2 singleton*singleton::getinstance()
3 11 returnm_instance;
12 }
但,由於編譯器等進行優化,導致記憶體讀寫存在reorder,有時導致雙檢查鎖的不安全性,處理辦法:
1 //c++ 11版本之後的跨平台實現最後是main方法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 }
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連乙個鍵盤等.單例模式有許多實現方法.第一次呼叫該類例項的時候才產生乙個新的該類例項,並在以後僅返回此例項,需要加鎖...