因?yàn)樵谠O(shè)計或開發(fā)中,肯定會有這么一種情況,一個類只能有一個對象被創(chuàng)建,如果有多個對象的話,可能會導(dǎo)致狀態(tài)的混亂和不一致。這種情況下,單例模式是最恰當(dāng)?shù)慕鉀Q辦法。它有很多種實(shí)現(xiàn)方式,各自的特性不相同,使用的情形也不相同。今天要實(shí)現(xiàn)的是常用的三種,分別是餓漢式、懶漢式和多線程式。
為撫順縣等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及撫順縣網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、撫順縣網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!通過單例模式, 可以做到:
1. 確保一個類只有一個實(shí)例被建立
2. 提供了一個對對象的全局訪問指針
3. 在不影響單例類的客戶端的情況下允許將來有多個實(shí)例
懶漢式的特點(diǎn)是延遲加載,比如配置文件,采用懶漢式的方法,顧名思義,懶漢么,很懶的,配置文件的實(shí)例直到用到的時候才會加載。。。。。。
class CSingleton { public: static CSingleton* GetInstance() { if ( m_pInstance == NULL ) m_pInstance = new CSingleton(); return m_pInstance; } private: CSingleton(){}; static CSingleton * m_pInstance; };
代碼很簡單,但是會存在內(nèi)存泄漏的問題,new出來的東西始終沒有釋放,下面是一種餓漢式的一種改進(jìn)。
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; } };
餓漢式的特點(diǎn)是一開始就加載了,如果說懶漢式是“時間換空間”,那么餓漢式就是“空間換時間”,因?yàn)橐婚_始就創(chuàng)建了實(shí)例,所以每次用到的之后直接返回就好了。
class CSingleton { private: CSingleton() { } public: static CSingleton * GetInstance() { static CSingleton instance; return &instance; } };
注:線程安全的通俗解釋 - 不管多個線程是怎樣的執(zhí)行順序和優(yōu)先級,或是wait,sleep,join等控制方式,如果一個類在多線程訪問下運(yùn)轉(zhuǎn)一切正常,并且訪問類不需要進(jìn)行額外的同步處理或者協(xié)調(diào),那么我們就認(rèn)為它是線程安全的。 線程安全的類應(yīng)當(dāng)封裝了所有必要的同步操作,調(diào)用者無需額外的同步。還有一點(diǎn):無狀態(tài)的類永遠(yuǎn)是線程安全的。
在餓漢式的單例類中,其實(shí)有兩個狀態(tài),單例未初始化和單例已經(jīng)初始化。假設(shè)單例還未初始化,有兩個線程同時調(diào)用GetInstance方法,這時執(zhí)行 m_pInstance == NULL 肯定為真,然后兩個線程都初始化一個單例,最后得到的指針并不是指向同一個地方,不滿足單例類的定義了,所以餓漢式的寫法會出現(xiàn)線程安全的問題!在多線程環(huán)境下,要對其進(jìn)行修改。
這里要處理的是懶漢模式。
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; }
C++中的單例模式
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。