設計模式 單例模式

2021-12-29 20:43:41 字數 2931 閱讀 7212

單例模式:

確保程式的某乙個類在執行的時候只生成乙個物件,擁有對它類似於全域性物件的訪問許可權。

模式分析:

例如很多時候我們在寫程式的時候會有類似於drivermanager,callmanager等等這樣的管理類,它們主要的功能就是為了管理一堆相似的物件。對於這種管理類,乙個程式一般只有乙個物件,畢竟我們寫出管理類的目的就是為了便於管理,管理類的物件多了也就失去了管理的意義了,而且還有一點我們在程式中肯定會有很多地方需要直接訪問到這個物件,畢竟乙個程式很多地方都需要通過管理類找到對應的driver,對應的call等等。

解決方案:

1,最簡單的我們可能定義乙個全域性物件

通過callmanager g_callmanager;建立乙個全域性物件,然後在需要地方通過extern callmanager g_callmanager;來獲取它的訪問許可權。咋聽起來不錯,但是從第一次寫程式的時候,就會有很多經驗豐富的老手告訴我們全域性物件的各種弊端,而且我們也沒有辦法確保物件只有乙個,畢竟你可以在**中隨時通過callmanager mymanager這樣類似**來建立物件。

2,單例模式

[cpp]

class callmanager 

return instance_; 

} private: 

static callmanager* instance_;//注意這個為靜態私有物件  

callmanager();//注意這個為私有  

} class callmanager

return instance_;

}private:

static callmanager* instance_;//注意這個為靜態私有物件

callmanager();//注意這個為私有

}[cpp]

static callmanager* callmanager::instance_ = null; 

static callmanager* callmanager::instance_ = null;分析:

為了確保你不能在外部通過callmanager mymanager等等其它類似的方案建立物件,其將建構函式定義為私有的,這樣就禁止了外部的顯式構造建立物件,根本編譯不過去。那你可能會問,那我還怎麼建立物件呢,畢竟我還需要乙個物件。強大的getinstance方法出現了,它通過訪問自己類的靜態成員instance_是否為空來決定是否建立物件,這樣可以給我們兩個保證:1,你可以建立物件,而且只會建立乙個,2你可以在其他任何地方訪問到這個物件,通過getinstance方法。如果你不是很懂靜態成員變數和靜態資料成員,建議找一些相關的文件看一下,加深理解。靜態成員變數instance_給予我們乙個類只有乙個變數的限制,靜態成員函式getinstance給予我們訪問私有靜態成員變數instance_的權利,同時還保證了只有乙個物件被建立。

延伸:1,如果你懂多執行緒,那麼你應該會發現上文中的**的問題,如果getinstance方法同時被兩個地方呼叫,那麼就有可能同時new兩次,這個是不可取的。通常的解決辦法是getinstance方法在系統初始化的時候就呼叫一次,確保物件的建立。我感覺這種方法很好,相當不建議用lock,因為這個方法用的地方會很多,加lock會很嚴重影響本來的效率。

2,new的callmanager什麼時候會被釋放?對於這種情況,我的建議是再建立乙個靜態destory方法,負責delete instance_。

[cpp]

static void destroyinstance()    

static void destroyinstance() 

3,呼叫destroyinstance有點繁瑣,畢竟需要考慮在什麼地方呼叫,出現異常沒有呼叫等等一些問題,那倒不如把這個問題拋給系統吧。使用區域性靜態物件。

[cpp]

public: 

callmanager* getinstance() 

public:

callmanager* getinstance()通過這種區域性靜態的使用既省去了destroyinstance的呼叫,同時可以確保它一定會被釋放,還省去了instance_成員變數,何樂而不為呢?建議採用。

不過依然需要注意,getinstance依然初始化需要呼叫一次,免去多執行緒的困擾,區域性靜態物件只有在第一次呼叫的時候才會分配記憶體,可以通過在callma的建構函式列印日誌來驗證這個結論。

靜態變數版本:

[cpp]

#include   

class callmanager 

~callmanager() 

private: 

callmanager() 

}; #include

class callmanager

~callmanager()

private:

callmanager()

};請注意雖然我將函式的實現寫在了類的宣告裡面,但是請注意這並不是我本意。我是為了簡單,其實應該分成h和cpp檔案的,這樣可以降低編譯依賴,而且缺省內聯也不是我們想要的,具體的細節不再贅述。

main驅動程式:

[cpp]

#include   

#include   

int main() 

#include

#include

int main()

輸出結果:

[cpp]

callmanager constructed... 

callmanager destructed... 

callmanager constructed...

callmanager destructed...與我們所想一致,由初始化構建,只構建一次,在main結束之後被自動釋放。wonderful。

後記:不知道我的這種敘述方式會不會有點過於口語化了,我只想把我在學習它的時候的所得所思所獲說出來,跟大家**一下,有些經驗希望能給大家帶來哪怕小小的幫助,描述的過程同樣是我再次回顧我的思路的過程,有錯誤歡迎指出,讓我也糾正我的錯誤,謝謝。

設計模式 單例模式

單例模式 singleton pattern 是乙個比較簡單的模式,其定義如下 ensure a class has only one instance,and provide a golbal point of acess to it.確保某乙個類只有乙個例項,而且自行例項化並且向整個系統提供這個...

設計模式 單例模式

class testsingleton static public function instance return self testsingleton private function clone public function setsinvar sinvar public function ...

設計模式 單例模式

單例模式的目的是保證類在系統中只被例項化一次,由該唯一的例項來為系統提供服務.單例模式主要用於保證服務的統一,比如獲取統一的編號服務,模仿oracle的序列生成等.但單例的使用需要謹慎,特別是在需要作負載均衡的地方,因為這種程式級的單例模式實際上只能保證在乙個應用中為單例.如果被多個應用載入,還是會...