• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            CG@CPPBLOG

            /*=========================================*/
            隨筆 - 76, 文章 - 39, 評論 - 137, 引用 - 0
            數(shù)據(jù)加載中……

            再論Singleton

            記得以前大家討論過Singleton三種寫法的優(yōu)劣,今天我又發(fā)現(xiàn)了一個新問題,在這里和大家分享一下。下面是三種Singleton的寫法:

             

             1 // 1st
             2 class Singleton{
             3     static Singleton inst;
             4 public:
             5     Singleton& GetInst(){
             6         return inst;
             7     }
             8 };
             9 Singleton Singleton::inst;
            10 // 2nd
            11 class Singleton{
            12     static Singleton* _inst;
            13 public:
            14     Singleton& GetInst(){
            15         if(_inst == NULL)
            16             _inst = new Singleton;
            17         return *_inst;
            18     }
            19 };
            20 // 3rd
            21 class Singleton{
            22 public:
            23     Singleton& GetInst(){
            24         static Singleton inst;
            25         return inst;
            26     }
            27 }

            我們已經(jīng)知道方法1沒有多線程問題,但編譯時分配內(nèi)存。方法2有多線程問題,在運行時分配內(nèi)存。方法3也有多線程問題,而且在編譯時分配內(nèi)存,但在運行時調(diào)用構(gòu)造函數(shù)。(多線程問題的解決方法在此不再贅述。)

            那么,我們可能就認為方法
            1雖然在編譯時分配內(nèi)存,但我們不在乎這點內(nèi)存,反正寫出來是要用的,這點內(nèi)存少不了,既避免了多線程,又避免了分配失敗。就用它了!

            不幸的是,方法1也有它自身的問題。今天我在構(gòu)造一個對象工廠時,期望通過全局變量,向工廠注冊派生類的生成方法時,方法1暴露了它的問題。比如我們在Singleton中有一個方法RegisterMethod(CallBack*),那么我可能這樣實現(xiàn)。

             

            1 //以下代碼是全局的,文件級作用域
            2 
            3 namespace{
            4     CBase* CreateDeriveObj()
            5     {
            6         return new(CDerive);
            7     }
            8     BOOL tmp = Singleton::GetInst().RegisterMethod(CreateDeriveObj);
            9 }//end of namespace
             

             

            結(jié)果發(fā)現(xiàn)在調(diào)用RegisterMethod()時,Singleton::inst 還沒有初始化(構(gòu)造函數(shù)沒有被調(diào)用)。究其原因是編譯器雖然在編譯時對其分配內(nèi)存,但是構(gòu)造函數(shù)是在運行時,在Main()函數(shù)前調(diào)用。而對于全局變量,編譯器是不保證初始化順序的!而這個例子就是tmp在構(gòu)造時, Singleton::inst 還沒有構(gòu)造。

            而這個問題的解決方法只有使用方法2或者方法3,考慮到我們不能在Main函數(shù)前使用new操作符,我用了方法3。又因為我有全局變量保證,就可以不考慮多線程問題了。

            要么是這個問題,要么是那個問題,你總要解決一個問題。

             

            posted on 2007-12-20 21:55 cuigang 閱讀(399) 評論(0)  編輯 收藏 引用 所屬分類: C/C++

            久久精品蜜芽亚洲国产AV| 久久亚洲精品无码观看不卡| 久久狠狠高潮亚洲精品| 狠狠色噜噜色狠狠狠综合久久| 亚洲αv久久久噜噜噜噜噜| 国内精品久久久久伊人av| 久久婷婷五月综合成人D啪| 日韩人妻无码精品久久免费一 | 久久国产精品一区二区| 亚洲国产精品久久久久| 一本久久精品一区二区| 国产∨亚洲V天堂无码久久久| 久久精品国产清自在天天线| 久久久久久毛片免费播放| 久久国产精品99久久久久久老狼| 亚洲国产成人精品女人久久久 | 久久精品aⅴ无码中文字字幕不卡 久久精品成人欧美大片 | 国产高潮国产高潮久久久| 久久综合亚洲鲁鲁五月天| 国产精品久久久久久久久| 久久综合香蕉国产蜜臀AV| 久久久久久一区国产精品| 91精品国产91久久| 国产精品日韩深夜福利久久| 亚洲AV日韩AV永久无码久久| 日本精品久久久久影院日本| 欧美久久综合九色综合| 91精品国产高清久久久久久国产嫩草 | 久久夜色精品国产噜噜麻豆| 久久无码AV中文出轨人妻| 欧美粉嫩小泬久久久久久久| 久久久久亚洲av毛片大| 久久久久久狠狠丁香| 久久精品人人做人人爽电影| 国产精品久久久久久| 久久久久久无码Av成人影院| 久久亚洲欧美国产精品| 国产精品久久久久影院嫩草| 国产高潮国产高潮久久久| 97精品国产97久久久久久免费| 久久强奷乱码老熟女网站|