無論是太陽下,還是風(fēng)雨中,都要成長!
前面對C++的Singleton模式的探討還都是針對通過靜態(tài)變量來創(chuàng)建對象。但學(xué)習(xí)嘛,多走點(diǎn)總不是壞事。
接下來就來看看通過 new 來創(chuàng)建單件對象的單件類設(shè)計(jì)。既然是用 new 來創(chuàng)建了,那自然就不能忽略需要用 delete 來釋放。
好了,先來看看代碼:
[單件類的線程安全性]
代碼中,類A和C都是單件類,且都是通過 new 來分配和創(chuàng)建單件對象,在對象的釋放上,也統(tǒng)一的使用Release函數(shù)封裝了delete操作,并手動調(diào)用。但A的單件和C的單件又是不同的,這個不同就在于 A 是通過將 new 出來的對象指針賦給成員變量,而 C 則將 new 出來的對象指針給了局部靜態(tài)變量。可別小看了這個區(qū)別哦!!就因?yàn)檫@一不同,結(jié)果 A 不是線程安全的,而 C 卻是線程安全的。當(dāng)然,也可以通過使用臨界區(qū)、互斥量等來是 A 變?yōu)榫€程安全,可是,該在什么時候去初始化臨界區(qū)或創(chuàng)建互斥量對象等呢?以臨界區(qū)為例,按常規(guī)的在 main 的頭部進(jìn)行臨界區(qū)的初始化,末尾則進(jìn)行臨界區(qū)的刪除;但是很不幸,程序崩潰了!!因?yàn)槿肿兞吭跇?gòu)造是調(diào)用了單件A,而單件A創(chuàng)建用到了臨界區(qū),可這是臨界區(qū)卻還沒有初始化。那么將這臨界區(qū)的初始化放到A的構(gòu)造呢?一樣使用先去初始化。放到A::GetInstance()內(nèi)呢?影響效率,且存在重復(fù)初始化。
放到B的構(gòu)造呢?還是被反復(fù)多次初始化了……。而且,有非B類的更先構(gòu)造并調(diào)用了單件A的全局對象呢?!
——看來,從線程安全考慮,單件類A的設(shè)計(jì)應(yīng)當(dāng)被否決了。
[單件類對象的釋放]
撇開線程安全問題不看,就上面的Demo,我們將會發(fā)現(xiàn)另一個嚴(yán)重問題——何時才能調(diào)用A和C的Release方法,釋放A和C的單件對象呢?如果,是如Demo中那樣,在main函數(shù)末尾進(jìn)行釋放,那么因?yàn)轭怋的幾個全局對象的析構(gòu),將發(fā)生如下的糟糕結(jié)果:
但是,如果我們把Release放入B的析構(gòu)中,則A將被多次的分配和釋放,而C則被多次調(diào)用析構(gòu)。無奈咯,考慮釋放的困難,這里的A和C的單件類設(shè)計(jì)方式看來也都還是否決的好!~
posted on 2012-03-13 00:55 青碧竹 閱讀(265) 評論(0) 編輯 收藏 引用 所屬分類: 設(shè)計(jì)模式
Powered by: C++博客 Copyright © 青碧竹