www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 公眾號精選 > 程序喵大人
[導讀]程序喵最近開始系統(tǒng)學習回顧設計模式,希望能把學到的東西分享給大家,今天總結(jié)下創(chuàng)建型模式中最經(jīng)典的單例模式。 “ ?? 什 么 是 單 例 模 式 ? ?” 這里首先介紹下什么是創(chuàng)建型模式,創(chuàng)建型模式主要解決對象的創(chuàng)建過程,封裝對象復雜的創(chuàng)建過程,解耦對象


程序喵最近開始系統(tǒng)學習回顧設計模式,希望能把學到的東西分享給大家,今天總結(jié)下創(chuàng)建型模式中最經(jīng)典的單例模式。


  
什 么 是 單 例 模 式 ?


 ”
這里首先介紹下什么是創(chuàng)建型模式,創(chuàng)建型模式主要解決對象的創(chuàng)建過程,封裝對象復雜的創(chuàng)建過程,解耦對象的創(chuàng)建代碼和對象的使用代碼。
而單例模式指的就是在系統(tǒng)里一個類只能產(chǎn)生一個實例,確保全局唯一。

怎么實現(xiàn)單例模式呢,常見的有以下幾種方法,這里程序喵只介紹線程安全的實現(xiàn):


  懶 漢 式 實 現(xiàn) 1

 ”

直接看代碼:
#include <iostream>#include <mutex>
class Singleton { public: static Singleton *GetInstance();
void Func() { std::cout << "Singleton Func \n"; }
private: Singleton() {} // 避免外部構造對象,想拿到類的實例只能通過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 check if (instance_ == nullptr) { // 1 std::unique_lock<std::mutex> lock(mutex_); if (instance_ == nullptr) { // 2 instance_ = new Singleton(); } } return instance_;}
int main() { Singleton::GetInstance()->Func(); return 0;}
這就是傳說中的 double check 方法,這里有幾個關鍵點:

1

為什么需要加鎖?加鎖的原因很簡單,為了確保線程安全。

2

您看過代碼可能也有些疑惑,明明加一次鎖和第二次的判斷就足夠了,為什么在加鎖之前還需要進行一次判斷呢?這里可以考慮只需要在判斷指針為空的時候才去加鎖,避免每次調(diào)用方法時都加鎖,可以減少加鎖解鎖帶來的額外開銷。

3

這里需要將類的構造函數(shù)和拷貝構造函數(shù)等設成私有函數(shù),避免外部構造類的實例,防止外部通過new關鍵字進行實例化。

  懶 漢 式 實 現(xiàn) 2
 ”

通過局部靜態(tài)變量的方式實現(xiàn),這種方法在C++11后是線程安全的,見代碼
#include <iostream>#include <mutex>
class Singleton { public: static Singleton& GetInstance() { static Singleton instance; return instance; }
void Func() { std::cout << "Singleton Func \n"; }
private: Singleton() {} // 避免外部構造對象,想拿到類的實例只能通過GetInstance() Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;
};
int main() { Singleton::GetInstance().Func(); return 0;}
C++11確保局部靜態(tài)變量創(chuàng)建時線程安全的,本人基本上用的單例都是使用這種方式。

  餓 漢 式 實 現(xiàn)
 ”

懶漢式指的是在需要實例的時候才去創(chuàng)建,就是上面的方法,而餓漢式則是提前創(chuàng)建好實例,外部需要實例的時候直接獲取這個已經(jīng)創(chuàng)建好的實例,看下餓漢式單例的實現(xiàn)吧:
#include <iostream>
class Singleton { public: static Singleton *GetInstance();
void Func() { std::cout << "Singleton Func \n"; }
private: Singleton() {} // 避免外部構造對象,想拿到類的實例只能通過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實現(xiàn)

在C++11后可以利用新特性實現(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é)

單例模式是一個經(jīng)典常用的設計模式,在面試過程中也經(jīng)常會被問到,當整個進程需要使用唯一的實例時,可以考慮使用單例模式,單例模式有幾個關鍵點:
  • 類只能有一個實例。
  • 外部用戶不能也無法自行對類進行實例化,實例化的操作需要類內(nèi)部去實現(xiàn)。
  • 整個進程共用一個類的實例,且需要是線程安全的。


往期推薦



免責聲明:本文內(nèi)容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉
關閉