日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

三种单例模式的C++实现

發(fā)布時(shí)間:2023/12/2 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 三种单例模式的C++实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡介

? ? ? ? 因?yàn)樵谠O(shè)計(jì)或開發(fā)中,肯定會(huì)有這么一種情況,一個(gè)類只能有一個(gè)對象被創(chuàng)建,如果有多個(gè)對象的話,可能會(huì)導(dǎo)致狀態(tài)的混亂和不一致。這種情況下,單例模式是最恰當(dāng)?shù)慕鉀Q辦法。它有很多種實(shí)現(xiàn)方式,各自的特性不相同,使用的情形也不相同。今天要實(shí)現(xiàn)的是常用的三種,分別是餓漢式、懶漢式和多線程式。

? ? ? ? 通過單例模式,?可以做到:

1. 確保一個(gè)類只有一個(gè)實(shí)例被建立?
2. 提供了一個(gè)對對象的全局訪問指針?
3. 在不影響單例類的客戶端的情況下允許將來有多個(gè)實(shí)例


懶漢式

? ? ? 懶漢式的特點(diǎn)是延遲加載,比如配置文件,采用懶漢式的方法,顧名思義,懶漢么,很懶的,配置文件的實(shí)例直到用到的時(shí)候才會(huì)加載。。。。。。

[cpp]?view plaincopy
  • class?CSingleton??
  • {??
  • public:??
  • static?CSingleton*?GetInstance()??
  • {??
  • ?????if?(?m_pInstance?==?NULL?)????
  • ?????????m_pInstance?=?new?CSingleton();??
  • ?????return?m_pInstance;??
  • }??
  • private:??
  • ????CSingleton(){};??
  • ????static?CSingleton?*?m_pInstance;??
  • };??

  • GetInstance()使用懶惰初始化,也就是說它的返回值是當(dāng)這個(gè)函數(shù)首次被訪問時(shí)被創(chuàng)建的。這是一種防彈設(shè)計(jì)——所有GetInstance()之后的調(diào)用都返回相同實(shí)例的指針:
    CSingleton* p1 = CSingleton :: GetInstance();
    CSingleton* p2 = p1->GetInstance();
    CSingleton & ref = * CSingleton :: GetInstance();
    對GetInstance稍加修改,這個(gè)設(shè)計(jì)模板便可以適用于可變多實(shí)例情況,如一個(gè)類允許最多五個(gè)實(shí)例。


    代碼很簡單,但是會(huì)存在內(nèi)存泄漏的問題,new出來的東西始終沒有釋放,下面是一種餓漢式的一種改進(jìn)。

    [cpp]?view plaincopy
  • class?CSingleton????
  • {????
  • private:????
  • ????CSingleton()????
  • ????{????
  • ????}????
  • ????static?CSingleton?*m_pInstance;????
  • ????class?CGarbo?????
  • ????{????
  • ????public:????
  • ????????~CGarbo()????
  • ????????{????
  • ????????????if(CSingleton::m_pInstance)????
  • ????????????????delete?CSingleton::m_pInstance;????
  • ????????}????
  • ????};????
  • ????static?CGarbo?Garbo;?????
  • public:????
  • ????static?CSingleton?*?GetInstance()????
  • ????{????
  • ????????if(m_pInstance?==?NULL)????
  • ????????????m_pInstance?=?new?CSingleton();????
  • ????????return?m_pInstance;????
  • ????}????
  • };????

  •   ? 在程序運(yùn)行結(jié)束時(shí),系統(tǒng)會(huì)調(diào)用CSingleton的靜態(tài)成員Garbo的析構(gòu)函數(shù),該析構(gòu)函數(shù)會(huì)刪除單例的唯一實(shí)例。使用這種方法釋放單例對象有以下特征:
    1.在單例類內(nèi)部定義專有的嵌套類。
    2.在單例類內(nèi)定義私有的專門用于釋放的靜態(tài)成員。
    3.利用程序在結(jié)束時(shí)析構(gòu)全局變量的特性,選擇最終的釋放時(shí)機(jī)。


    餓漢式

    ? ? ? ?餓漢式的特點(diǎn)是一開始就加載了,如果說懶漢式是“時(shí)間換空間”,那么餓漢式就是“空間換時(shí)間”,因?yàn)橐婚_始就創(chuàng)建了實(shí)例,所以每次用到的之后直接返回就好了。

    [cpp]?view plaincopy
  • class?CSingleton????
  • {????
  • private:????
  • ????CSingleton()??????
  • ????{????
  • ????}????
  • public:????
  • ????static?CSingleton?*?GetInstance()????
  • ????{????
  • ????????static?CSingleton?instance;?????
  • ????????return?&instance;????
  • ????}????
  • };????

  • ? ? ? 餓漢式是線程安全的,在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對象供系統(tǒng)使用,以后不再改變,懶漢式如果在創(chuàng)建實(shí)例對象時(shí)不加上synchronized則會(huì)導(dǎo)致對對象的訪問不是線程安全的。

    注:線程安全的通俗解釋 - 不管多個(gè)線程是怎樣的執(zhí)行順序和優(yōu)先級,或是wait,sleep,join等控制方式,如果一個(gè)類在多線程訪問下運(yùn)轉(zhuǎn)一切正常,并且訪問類不需要進(jìn)行額外的同步處理或者協(xié)調(diào),那么我們就認(rèn)為它是線程安全的。 線程安全的類應(yīng)當(dāng)封裝了所有必要的同步操作,調(diào)用者無需額外的同步。還有一點(diǎn):無狀態(tài)的類永遠(yuǎn)是線程安全的。

    ? ? ? ??

    ? ? ? ? ?在餓漢式的單例類中,其實(shí)有兩個(gè)狀態(tài),單例未初始化和單例已經(jīng)初始化。假設(shè)單例還未初始化,有兩個(gè)線程同時(shí)調(diào)用GetInstance方法,這時(shí)執(zhí)行?m_pInstance == NULL 肯定為真,然后兩個(gè)線程都初始化一個(gè)單例,最后得到的指針并不是指向同一個(gè)地方,不滿足單例類的定義了,所以餓漢式的寫法會(huì)出現(xiàn)線程安全的問題!在多線程環(huán)境下,要對其進(jìn)行修改。


    多線程下的單例模式

    ? ? ? ? 這里要處理的是懶漢模式。

    [cpp]?view plaincopy
  • class?Singleton??
  • {??
  • private:??
  • ????static?Singleton*?m_instance;??
  • ????Singleton(){}??
  • public:??
  • ????static?Singleton*?getInstance();??
  • };??
  • ??
  • Singleton*?Singleton::getInstance()??
  • {??
  • ????if(NULL?==?m_instance)??
  • ????{??
  • ????????Lock();//借用其它類來實(shí)現(xiàn),如boost??
  • ????????if(NULL?==?m_instance)??
  • ????????{??
  • ????????????m_instance?=?new?Singleton;??
  • ????????}??
  • ????????UnLock();??
  • ????}??
  • ????return?m_instance;??
  • }??

  • 使用double-check來保證thread safety.但是如果處理大量數(shù)據(jù)時(shí),該鎖才成為嚴(yán)重的性能瓶頸。 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的三种单例模式的C++实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。