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

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


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


  
什 么 是 單 例 模 式 ?


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

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


  懶 漢 式 實(shí) 現(xiàn) 1

 ”

直接看代碼:
#include <iostream>#include <mutex>
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 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 方法,這里有幾個(gè)關(guān)鍵點(diǎn):

1

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

2

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

3

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

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

通過局部靜態(tài)變量的方式實(shí)現(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() {} // 避免外部構(gòu)造對象,想拿到類的實(shí)例只能通過GetInstance() Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;
};
int main() { Singleton::GetInstance().Func(); return 0;}
C++11確保局部靜態(tài)變量創(chuàng)建時(shí)線程安全的,本人基本上用的單例都是使用這種方式。

  餓 漢 式 實(shí) 現(xiàn)
 ”

懶漢式指的是在需要實(shí)例的時(shí)候才去創(chuàng)建,就是上面的方法,而餓漢式則是提前創(chuàng)建好實(shí)例,外部需要實(shí)例的時(shí)候直接獲取這個(gè)已經(jīng)創(chuàng)建好的實(shí)例,看下餓漢式單例的實(shí)現(xiàn)吧:
#include <iostream>
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)

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

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


往期推薦



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

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