久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C++中實現(xiàn)Singleton的正確方法

 just_person 2012-02-13

如果某個類管理了系統(tǒng)中唯一的某種資源,,那么我們只能創(chuàng)建該類的一個實例,,此時用到singleton設(shè)計模式(后面為了簡化將省略“設(shè)計模式”四個字)就比較合適了。然而,,如果不注意實現(xiàn)方法,,就很有可能會讓我們碰到一些莫名其妙的錯誤。圖1是經(jīng)過簡化所得到的一個實現(xiàn)錯誤的例子,。

  1. main.c 
  2. 00001: #include <iostream> 
  3. 00002: 
  4. 00003: using namespace std; 
  5. 00004: 
  6. 00005: class singleton1_t 
  7. 00006: { 
  8. 00007: public
  9. 00008:     static singleton1_t *instance () 
  10. 00009:     { 
  11. 00010:         return &instance_; 
  12. 00011:     } 
  13. 00012: 
  14. 00013:     void count_increase () {count_ ++;} 
  15. 00014:     int count () const {return count_;} 
  16. 00015: 
  17. 00016: private
  18. 00017:     singleton1_t (): count_ (0) {} 
  19. 00018:     ~singleton1_t () {} 
  20. 00019: 
  21. 00020:     static singleton1_t instance_; 
  22. 00021:     int count_; 
  23. 00022: }; 
  24. 00023: 
  25. 00024: class singleton2_t 
  26. 00025: { 
  27. 00026: public
  28. 00027:     static singleton2_t *instance () 
  29. 00028:     { 
  30. 00029:         return &instance_; 
  31. 00030:     } 
  32. 00031: 
  33. 00032: private
  34. 00033:     singleton2_t () {singleton1_t::instance ()->count_increase ();} 
  35. 00034:     ~singleton2_t () {} 
  36. 00035: 
  37. 00036:     static singleton2_t instance_; 
  38. 00037: }; 
  39. 00038: 
  40. 00039: singleton2_t singleton2_t::instance_; 
  41. 00040: singleton1_t singleton1_t::instance_; 
  42. 00041: 
  43. 00042: int main () 
  44. 00043: { 
  45. 00044:     (void) singleton2_t::instance (); 
  46. 00045:     cout << "count = " << singleton1_t::instance ()->count () << endl; 
  47. 00046:     return 0; 
  48. 00047: } 
圖1 
圖中的兩個類在實現(xiàn)singleton時都將類的構(gòu)造和析構(gòu)函數(shù)的對外可視性設(shè)為private,,這是實現(xiàn)singleton首先要注意的一個點。通過這一手段,,有助于預(yù)防他人粗心地定義類實例,。

圖中的singleton2_t類在其構(gòu)造函數(shù)中調(diào)用singleton1_t類的count_increase ()方法使計數(shù)加一。第44行的代碼用于代表使用singleton2_t實例,。第46行代碼則顯示singleton1_t類的記數(shù)信息,。圖2示例了該程序的運行結(jié)果。
  1. g++ main.cpp -o singleton.exe 
  2. ./singleton.exe 
  3. count = 0 
圖2 
是不是對于最終的顯示計數(shù)為0而不是1感到奇怪,?錯誤發(fā)生的原因在于,,singleton2_t類實例的構(gòu)造是先于singleton1_t類的,當singleton1_t類的實例在最后構(gòu)造時會把count_變量置成0,,從而覆蓋singleton2_t的構(gòu)造函數(shù)所引起的變更,。

盡管這是一個精心設(shè)計的錯誤,但在大型項目中出現(xiàn)這類錯誤的可能性卻并不小,。因為在現(xiàn)實項目中,,singleton1_t和singleton2_t兩個類的實現(xiàn)很可能是在不同的源文件中,這勢必造成兩個類實例的初始化順序會因鏈接順序不同而不同,,《
揭示C++中全局類變量的構(gòu)造與析構(gòu)順序》一文介紹了這是為什么,。

在本例中,如果將第39行和第40行的代碼進行對調(diào)就不會出現(xiàn)這種奇怪的現(xiàn)象,,但這不是解決問題的終極方法,。更好的方法需要更改singleton的實現(xiàn)方法,圖3示例了一種新的實現(xiàn)方法,。
  1. main.c 
  2. 00001: #include <iostream> 
  3. 00002: 
  4. 00003: using namespace std; 
  5. 00004: 
  6. 00005: class singleton1_t 
  7. 00006: { 
  8. 00007: public
  9. 00008:     static singleton1_t *instance () 
  10. 00009:     { 
  11. 00010:         if (0 == p_instance_) { 
  12. 00011:             p_instance_ = new singleton1_t; 
  13. 00012:         } 
  14. 00013:         return p_instance_; 
  15. 00014:     } 
  16. 00015: 
  17. 00016:     void count_increase () {count_ ++;} 
  18. 00017:     int count () const {return count_;} 
  19. 00018: 
  20. 00019: private
  21. 00020:     singleton1_t (): count_ (0) {} 
  22. 00021:     ~singleton1_t () {} 
  23. 00022: 
  24. 00023:     static singleton1_t *p_instance_; 
  25. 00024:     int count_; 
  26. 00025: }; 
  27. 00026: 
  28. 00027: class singleton2_t 
  29. 00028: { 
  30. 00029: public
  31. 00030:     static singleton2_t *instance () 
  32. 00031:     { 
  33. 00032:         if (0 == p_instance_) { 
  34. 00033:             p_instance_ = new singleton2_t; 
  35. 00034:         } 
  36. 00035:         return p_instance_; 
  37. 00036:     } 
  38. 00037: 
  39. 00038: private
  40. 00039:     singleton2_t () {singleton1_t::instance ()->count_increase ();} 
  41. 00040:     ~singleton2_t () {} 
  42. 00041: 
  43. 00042:     static singleton2_t *p_instance_; 
  44. 00043: }; 
  45. 00044: 
  46. 00045: singleton2_t *singleton2_t::p_instance_ = 0; 
  47. 00046: singleton1_t *singleton1_t::p_instance_ = 0; 
  48. 00047: 
  49. 00048: int main () 
  50. 00049: { 
  51. 00050:     singleton2_t::instance (); 
  52. 00051:     cout << "count = " << singleton1_t::instance ()->count () << endl; 
  53. 00052:     return 0; 
  54. 00053: } 
圖3 
新實現(xiàn)最大的變化,,在于將以前的類靜態(tài)變量從類實例變成了類指針,并在instance()函數(shù)中需要時通過new操作符創(chuàng)建類實例,。指針在C++中仍是當作一種原始數(shù)據(jù)類型處理的,,其初始化與類實例的初始化不同,,不需調(diào)用類構(gòu)造函數(shù)。在這一實現(xiàn)中,,兩個類的靜態(tài)變量p_instance_的初始化都是在程序的.bss段初始化時一次性完成的,。
 
這一實現(xiàn)中由于類的實例是通過new操作符獲得的,所以需要為類定義釋放實例的函數(shù)(圖中省略了),,并由在合適的時機調(diào)用,。為了省去這類麻煩,作者更推崇圖4所示的實現(xiàn)方式,。
  1. main.c 
  2. 00005: class singleton1_t 
  3. 00006: { 
  4. 00007: public
  5. 00008:     static singleton1_t *instance () 
  6. 00009:     { 
  7. 00010:         if (0 == p_instance_) { 
  8. 00011:             static singleton1_t instance; 
  9. 00012:             p_instance_ = &instance; 
  10. 00013:         } 
  11. 00014:         return p_instance_; 
  12. 00015:     } 
  13. 00016: 
  14. 00017:     void count_increase () {count_ ++;} 
  15. 00018:     int count () const {return count_;} 
  16. 00019: 
  17. 00020: private
  18. 00021:     singleton1_t (): count_ (0) {} 
  19. 00022:     ~singleton1_t () {} 
  20. 00023: 
  21. 00024:     static singleton1_t *p_instance_; 
  22. 00025:     int count_; 
  23. 00026: }; 
圖4 
通過在函數(shù)內(nèi)部定義靜態(tài)變量的方法獲得類實例,,一方面簡化了類接口的實現(xiàn),另一方面又降低了因為忘記調(diào)用釋放接口函數(shù)而導(dǎo)致內(nèi)存泄漏的可能,。需要提醒的是,,在這種實現(xiàn)方法中,類實例的構(gòu)造是發(fā)生在各類的instance()函數(shù)第一次被調(diào)用時,,而各實例的析構(gòu)又是以與構(gòu)造相反的順序進行的,,且后者是由編程語言環(huán)境所保證的。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多