保證乙個類僅有乙個例項,並提供乙個訪問他的全域性訪問點。通常我們可以讓乙個全域性變數使得乙個物件被訪問,但它不能防止你例項化多個物件。乙個最好的辦法就是,讓類自身負責儲存它的唯一例項。這個類可以保證沒有其他例項可以被建立,並且可以提供乙個訪問該例項的介面。其uml圖如下:
其示例**如下:
// singeltonmodel.h檔案
#pragma once
// 執行緒不安全類
class
singelton
static singelton * m_singel;
public
:static singelton *
getinstance()
return m_singel;}}
;singelton * singelton::m_singel =
nullptr
;
測試**如下:
#include
#include
"singeltonmodel.h"
intmain()
void
func2()
intmain()
輸出結果如下圖:
由上圖可看出,建立了兩次例項,兩個執行緒得到的例項並不是同乙個。這是因為兩個執行緒同時執行,當呼叫getinstance()時,例項並沒有建立,於是兩個執行緒都進入了建立例項的**塊,於是就建立了兩個例項。而第乙個被建立的例項被頂替後也沒有被釋放,這就是記憶體洩漏,還有先呼叫到建立例項的執行緒還得到了錯誤的例項,這樣會造成邏輯錯誤的。
解決辦法有兩種,一種辦法是在所有要訪問該類例項的**執行前該類先建立例項,另一種是在該類的訪問例項的**中加入執行緒同步的內容。例項**如下:
方法一:
#include
#include
#include
#include
"singeltonmodel.h"
void
func1()
void
func2()
intmain()
輸出結果如下圖:
方法二:
// singeltonmodel.h檔案
#include
#pragma once
// 執行緒安全類
class
singeltonthread
static singeltonthread * m_instance;
static std::mutex m_mutex;
public
:static singeltonthread *
getinstance()
return m_instance;}}
;singeltonthread * singeltonthread::m_instance =
nullptr
;std::mutex singeltonthread::m_mutex;
測試**如下:
#include
#include
#include
#include
"singeltonmodel.h"
void
func1()
void
func2()
intmain()
{using
namespace std;
// 單例模式
// 執行緒安全
std::thread thread1
(func1)
,thread2
(func2)
; thread1.
detach()
; thread2.
detach()
; std::cout <<
"主線程"
<< std::endl;
getchar()
return
0;
輸出結果如下圖:
這兩種方法都各有優勢,方法一實現簡單,但在複雜的系統中不太安全。方法二實現稍微複雜,而且每次訪問例項都要lock(mutex),消耗更大。但是方法二在任何情況下都很安全。總之方法一適合在系統不是太複雜的情況下使用,方法二在系統比較複雜的情況下使用。
C 設計模式之單例模式
在遊戲開發過程中,我們時常會遇到單例模式的運用場景。比如你遊戲當中的最終boss,你希望你的boss只能有乙個,所以這裡你就可以用單例模式 那麼什麼是單例模式呢?看下面的 分析。include include using namespace std class singleton public st...
C 設計模式之單例模式
設計模式是以理論的高度,總結了開發過程中的一多種不同的方法,在各種設計模式中,它們都有著不同實現方式,所起的作用也不相同,我最近看了部分設計模式,主要是以我自己的理解來闡述對它們的看法。我們可以看到單例的大概實現是很簡單的。幾個需要注意的地方是 只有當我們的建構函式為私有時,此時,我們在類外部就不能...
C 設計模式之 單例模式
單例模式,故名思義,其意圖是保證乙個類只有乙個例項,並提供乙個訪問它的全域性訪問點,該例項被所有的程式模組共享.在很多地方要用到這種設計模式,如系統的日誌輸出,作業系統的視窗,乙個pc連乙個鍵盤等.單例模式有許多實現方法.第一次呼叫該類例項的時候才產生乙個新的該類例項,並在以後僅返回此例項,需要加鎖...