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