設(shè)計模式之單例模式
時間:2020-08-19 00:47:26
手機(jī)看文章
掃描二維碼
隨時隨地手機(jī)看文章
[導(dǎo)讀]程序喵最近開始系統(tǒng)學(xué)習(xí)回顧設(shè)計模式,希望能把學(xué)到的東西分享給大家,今天總結(jié)下創(chuàng)建型模式中最經(jīng)典的單例模式。 “ ?? 什 么 是 單 例 模 式 ? ?” 這里首先介紹下什么是創(chuàng)建型模式,創(chuàng)建型模式主要解決對象的創(chuàng)建過程,封裝對象復(fù)雜的創(chuàng)建過程,解耦對象
程序喵最近開始系統(tǒng)學(xué)習(xí)回顧設(shè)計模式,希望能把學(xué)到的東西分享給大家,今天總結(jié)下創(chuàng)建型模式中最經(jīng)典的單例模式。
而單例模式指的就是在系統(tǒng)里一個類只能產(chǎn)生一個實(shí)例,確保全局唯一。
“
懶 漢 式 實(shí) 現(xiàn) 1
”
class Singleton {public:static Singleton *GetInstance();void Func() { std::cout << "Singleton Func \n"; }private:Singleton() {} // 避免外部構(gòu)造對象,想拿到類的實(shí)例只能通過GetInstance()Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton *instance_;static std::mutex mutex_;};Singleton *Singleton::instance_ = nullptr;std::mutex Singleton::mutex_;Singleton *Singleton::GetInstance() {// double checkif (instance_ == nullptr) { // 1std::unique_lock<std::mutex> lock(mutex_);if (instance_ == nullptr) { // 2instance_ = new Singleton();}}return instance_;}int main() {Singleton::GetInstance()->Func();return 0;}
為什么需要加鎖?加鎖的原因很簡單,為了確保線程安全。
您看過代碼可能也有些疑惑,明明加一次鎖和第二次的判斷就足夠了,為什么在加鎖之前還需要進(jìn)行一次判斷呢?這里可以考慮只需要在判斷指針為空的時候才去加鎖,避免每次調(diào)用方法時都加鎖,可以減少加鎖解鎖帶來的額外開銷。
這里需要將類的構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)等設(shè)成私有函數(shù),避免外部構(gòu)造類的實(shí)例,防止外部通過new關(guān)鍵字進(jìn)行實(shí)例化。
“
懶 漢 式 實(shí) 現(xiàn) 2
”
class Singleton {public:static Singleton& GetInstance() {static Singleton instance;return instance;}void Func() { std::cout << "Singleton Func \n"; }private:Singleton() {} // 避免外部構(gòu)造對象,想拿到類的實(shí)例只能通過GetInstance()Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;};int main() {Singleton::GetInstance().Func();return 0;}
“
餓 漢 式 實(shí) 現(xiàn)
”
class Singleton {public:static Singleton *GetInstance();void Func() { std::cout << "Singleton Func \n"; }private:Singleton() {} // 避免外部構(gòu)造對象,想拿到類的實(shí)例只能通過GetInstance()Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton *instance_;};Singleton *Singleton::instance_ = new Singleton();Singleton *Singleton::GetInstance() {return instance_;}int main() {Singleton::GetInstance()->Func();return 0;}
“
std::call_once實(shí)現(xiàn) ”
template <typename T>class SingleTon {public:static T& instance() {std::call_once(once_, &SingleTon::init);return *value_;}private:SingleTon();~SingleTon();SingleTon(const SingleTon&) = delete;SingleTon& operator=(const SingleTon&) = delete;static void init() { value_ = new T(); }static T* value_;static std::once_flag once_;};
總結(jié)
-
類只能有一個實(shí)例。 -
外部用戶不能也無法自行對類進(jìn)行實(shí)例化,實(shí)例化的操作需要類內(nèi)部去實(shí)現(xiàn)。 -
整個進(jìn)程共用一個類的實(shí)例,且需要是線程安全的。
往期推薦
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!





