關(guān)于C++中Singleton類實(shí)例析構(gòu)的討論zz_第1頁
關(guān)于C++中Singleton類實(shí)例析構(gòu)的討論zz_第2頁
關(guān)于C++中Singleton類實(shí)例析構(gòu)的討論zz_第3頁
關(guān)于C++中Singleton類實(shí)例析構(gòu)的討論zz_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、 關(guān)于C+中Singleton類實(shí)例析構(gòu)的討論zz單例模式也稱為單件模式、單模式,可能是使最泛的設(shè)計(jì)模式。其意圖是保證個類僅有個實(shí)例,并提供個訪問它的全局訪問點(diǎn),該實(shí)例被所有程序模塊共享。有很多地需要這樣的功能模塊,如系統(tǒng)的志輸出,GUI應(yīng)必須是單標(biāo),MODEM的聯(lián)接需要條且只需要條電話線,操作系統(tǒng)只能有個窗管理器,臺PC連個鍵盤。單例模式有許多種實(shí)現(xiàn)法,在C+中,甚可以直接個全局變量做到這點(diǎn),但這樣的代碼顯的很不優(yōu)雅。 使全局對象能夠保證便地訪問實(shí)例,但是不能保證只聲明個對象也就是說除了個全局實(shí)例外,仍然能創(chuàng)建相同類的本地實(shí)例。設(shè)計(jì)模式書中給出了種很不錯的實(shí)現(xiàn),定義個單例類,使類的私有靜態(tài)指

2、針變量指向類的唯實(shí)例,并個公有的靜態(tài)法獲取該實(shí)例。單例模式通過類本來管理其唯實(shí)例,這種特性提供了解決問題的法。唯的實(shí)例是類的個普通對象,但設(shè)計(jì)這個類時,讓它只能創(chuàng)建個實(shí)例并提供對此實(shí)例的全局訪問。唯實(shí)例類Singleton在靜態(tài)成員函數(shù)中隱藏創(chuàng)建實(shí)例的操作。習(xí)慣上把這個成員函數(shù)叫做Instance(),它的返回值是唯實(shí)例的指針。定義如下:class CSingleton/其他成員public:static CSingleton* GetInstance()if ( m_pInstance = NULL ) /判斷是否第次調(diào)m_pInstance = new CSingleton();retur

3、n m_pInstance;private:CSingleton();static CSingleton * m_pInstance;戶訪問唯實(shí)例的法只有GetInstance()成員函數(shù)。如果不通過這個函數(shù),任何創(chuàng)建實(shí)例的嘗試都將失敗,因?yàn)轭惖臉?gòu)造函數(shù)是私有的。GetInstance()使懶惰初始化,也就是說它的返回值是當(dāng)這個函數(shù)次被訪問時被創(chuàng)建的。這是種防彈設(shè)計(jì)所有GetInstance()之后的調(diào)都返回相同實(shí)例的指針:CSingleton* p1 = CSingleton : GetInstance();CSingleton* p2 = p1-GetInstance();CSinglet

4、on & ref = * CSingleton : GetInstance();對GetInstance稍加修改,這個設(shè)計(jì)模板便可以適于可變多實(shí)例情況,如個類允許最多五個實(shí)例。單例類CSingleton有以下特征: 它有個指向唯實(shí)例的靜態(tài)指針m_pInstance,并且是私有的;它有個公有的函數(shù),可以獲取這個唯的實(shí)例,并且在需要的時候創(chuàng)建該實(shí)例;它的構(gòu)造函數(shù)是私有的,這樣就不能從別處創(chuàng)建該類的實(shí)例。多數(shù)時候,這樣的實(shí)現(xiàn)都不會出現(xiàn)問題。有經(jīng)驗(yàn)的讀者可能會問,m_pInstance指向的空間什么時候釋放呢?更嚴(yán)重的問題是,該實(shí)例的析構(gòu)函數(shù)什么時候執(zhí)?如果在類的析構(gòu)為中有必須的操作,如關(guān)閉件,釋放外

5、部資源,那么上的代碼法實(shí)現(xiàn)這個要求。我們需要種法,正常的刪除該實(shí)例??梢栽诔绦蚪Y(jié)束時調(diào)GetInstance(),并對返回的指針掉delete操作。這樣做可以實(shí)現(xiàn)功能,但不僅很丑陋,且容易出錯。因?yàn)檫@樣的附加代碼很容易被忘記,且也很難保證在delete之后,沒有代碼再調(diào)GetInstance函數(shù)。個妥善的法是讓這個類知道在合適的時候把刪除,或者說把刪除的操作掛在操作系統(tǒng)中的某個合適的點(diǎn)上,使其在恰當(dāng)?shù)臅r候被動執(zhí)。我們知道,程序在結(jié)束的時候,系統(tǒng)會動析構(gòu)所有的全局變量。事實(shí)上,系統(tǒng)也會析構(gòu)所有的類的靜態(tài)成員變量,就像這些靜態(tài)成員也是全局變量樣。利這個特征,我們可以在單例類中定義個這樣的靜態(tài)成員變

6、量,它的唯作就是在析構(gòu)函數(shù)中刪除單例類的實(shí)例。如下的代碼中的CGarbo類(Garbo意為垃圾):class CSingleton/其他成員public:static CSingleton* GetInstance();private:CSingleton();static CSingleton * m_pInstance;class CGarbo /它的唯作就是在析構(gòu)函數(shù)中刪除CSingleton的實(shí)例public:CGarbo()if( CSingleton:m_pInstance )delete CSingleton:m_pInstance;Static CGabor Garbo; /定

7、義個靜態(tài)成員,程序結(jié)束時,系統(tǒng)會動調(diào)它的析構(gòu)函數(shù);類CGarbo被定義為CSingleton的私有內(nèi)嵌類,以防該類被在其他地濫。程序運(yùn)結(jié)束時,系統(tǒng)會調(diào)CSingleton的靜態(tài)成員Garbo的析構(gòu)函數(shù),該析構(gòu)函數(shù)會刪除單例的唯實(shí)例。使這種法釋放單例對象有以下特征: 在單例類內(nèi)部定義專有的嵌套類;在單例類內(nèi)定義私有的專門于釋放的靜態(tài)成員;利程序在結(jié)束時析構(gòu)全局變量的特性,選擇最終的釋放時機(jī);使單例的代碼不需要任何操作,不必關(guān)對象的釋放。進(jìn)步的討論但是添加個類的靜態(tài)對象,總是讓不太滿意,所以有如下法來重現(xiàn)實(shí)現(xiàn)單例和解決它相應(yīng)的問題,代碼如下:class CSingleton/其他成員public:

8、static Singleton &GetInstance()static Singleton instance;return instance;private:Singleton() ;使局部靜態(tài)變量,常強(qiáng)的法,完全實(shí)現(xiàn)了單例的特性,且代碼量更少,也不擔(dān)單例銷毀的問題。但使此種法也會出現(xiàn)問題,當(dāng)如下法使單例時問題來了,Singleton singleton = Singleton : GetInstance();這么做就出現(xiàn)了個類拷貝的問題,這就違背了單例的特性。產(chǎn)這個問題原因在于:編譯器會為類成個默認(rèn)的構(gòu)造函數(shù),來持類的拷貝。最后沒有辦法,我們要禁類拷貝和類賦值,禁程序員這種式來使單例,當(dāng)

9、時領(lǐng)導(dǎo)的意思是GetInstance()函數(shù)返回個指針不是返回個引,函數(shù)的代碼改為如下:static Singleton *GetInstance()static Singleton instance;return &instance;但我總覺的不好,為什么不讓編譯器不這么呢。這時我才想起可以顯的命類拷貝的構(gòu)造函數(shù),和重載 = 操作符,新的單例類如下:class Singleton/其他成員 public:static Singleton &GetInstance()static Singleton instance;return instance;private:Singleton() ;S

10、ingleton(const Singleton);Singleton & operate = (const Singleton&);關(guān)于Singleton(const Singleton); 和 Singleton & operate = (const Singleton&); 函數(shù),需要聲明成私的,并且只聲明不實(shí)現(xiàn)。這樣,如果上的式來使單例時,不管是在友元類中還是其他的,編譯器都是報(bào)錯。不知道這樣的單例類是否還會有問題,但在程序中這樣使已經(jīng)基本沒有問題了。優(yōu)化Singleton類,使之適于單線程應(yīng)Singleton使操作符new為唯實(shí)例分配存儲空間。因?yàn)閚ew操作符是線程安全的,在多線程應(yīng)中你可以使此設(shè)計(jì)模板,但是有個缺陷:就是在應(yīng)程序終之前必須delete摧毀實(shí)例。否則,不僅導(dǎo)致內(nèi)存溢出,還要造成不可預(yù)測的為,因?yàn)镾ingleton的析構(gòu)函數(shù)將根本不會被調(diào)。通過使本地靜態(tài)實(shí)例代替動態(tài)實(shí)例,單線程應(yīng)可以很容易避免這個問題。下是與上的GetInstance()稍有不同的實(shí)現(xiàn),這個實(shí)現(xiàn)專門于單線程應(yīng):CSingleton* CSingleton :

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論