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





