• <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>
            隨筆-90  評(píng)論-947  文章-0  trackbacks-0

            我的觀點(diǎn)可能有點(diǎn)激進(jìn),我覺得單件模式啥也不是,純粹是個(gè)全局變量的貞潔牌坊而已。全局變量如果有必要,用就用了,何必偽裝;如無必要,就算穿上單件模式的馬甲,到頭來也會(huì)搞得一片狼籍——隨處可見GetInstance。

            歡迎討論~

            posted on 2010-03-29 10:58 溪流 閱讀(4469) 評(píng)論(63)  編輯 收藏 引用 所屬分類: C++

            評(píng)論:
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 11:43 | 空明流轉(zhuǎn)
            單間的實(shí)例限定和訪問可控,你能global做到撒?盡白扯。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 11:48 | 溪流
            @空明流轉(zhuǎn)
            沒白扯。
            如果要限定單一實(shí)例,這個(gè)類實(shí)際上需要是個(gè)靜態(tài)類。

            訪問可控?我就不懂了,,單件模式訪問哪里可控?  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 12:21 | 陳梓瀚(vczh)
            @空明流轉(zhuǎn)
            最容易的辦法就是

            [ShitOperator.h]

            class IShitOperator
            {
            public:
            virtual void DoShit()=0;
            };

            extern IShitOperator* GetShitOperator();

            //--------------------------------------------------------
            [ShitOperator.cpp]

            class ShitOperator : public IShitOperator
            {
            ..
            } shitOperator;

            IShitOperator* GetShitOperator()
            {
            return &shitOperator;
            }

            -------------------------------------------------------------

            我TM就不知道一個(gè)單件哪來那么多問題,拿一個(gè)純虛類一套,不管三七二十一你用沒用到反正我在main之前先創(chuàng)建好了,還有那么多亂七八糟的鎖啊,private constructor什么的干嘛呢。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要?[未登錄] 2010-03-29 12:34 | x
            只是一個(gè)構(gòu)建模式而已,如果到處都是,你可以提交一個(gè)反模式  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 12:35 | 風(fēng)雷云雪電
            就C++來言,全局變量和單例是差不都,不過單例相對(duì)于全局變量來說,程序員不容易出錯(cuò),程序員有可能重新實(shí)例化一個(gè)類而不是使用全局變量。
            在其他語言中如Java,C#,單例是非常有必要的  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 13:07 | 溪流
            @風(fēng)雷云雪電
            就C++而言,如果是不得不用的全局?jǐn)?shù)據(jù),那么它應(yīng)該早早的就被規(guī)定好了的,而且只要做到不跨文件使用,出錯(cuò)的幾率并不大。如果只能有一個(gè)實(shí)例,那么這個(gè)class可以靜態(tài)化。如果不許實(shí)例化,可以private掉ctor。

            對(duì)于java,C#,單例又體現(xiàn)在哪里?C#已經(jīng)支持了 static class 的寫法了  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 13:12 | 溪流
            @x
            因?yàn)槲铱吹酵Χ嗟胤蕉颊f單例模式如何如何了得,但是想不通,所以有此感慨。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 13:13 | 溪流
            @陳梓瀚(vczh)
            例子看懂了。但我看不太明白你的觀點(diǎn),呵呵  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 13:37 | Kevin Lynx
            @溪流
            這個(gè)問題某種角度來看,就如同對(duì)成員變量不管應(yīng)用情景如何都提供Get/Set一樣,同public一樣了。

            我覺得唯一的區(qū)別,還是一種安全控制吧:
            class Singleton
            {
            public:
            static Singleton &GetInstance() { static Singleton ob; .... }
            private:
            Singleton() { ... }
            Singleton( const Singleton & ) ...
            };
            那么,這個(gè)Singleton對(duì)象就只存在一份。

            當(dāng)然,也有單件不作constructor的private限制的。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 13:55 | qiaojie
            單件模式確實(shí)是一個(gè)錯(cuò)誤。但是不應(yīng)該用全局變量代替單件,而是應(yīng)該用一組全局函數(shù)帶代替單件模式,就像系統(tǒng)API那樣。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 13:59 | 溪流
            @qiaojie
            一組全局函數(shù)如果一定要完全OOP則可以封裝到“靜態(tài)類”里面:
            class AAA
            {
            public:
            static void foo();
            static void bar();
            //...

            private:
            AAA();
            };  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 14:10 | 溪流
            @Kevin Lynx
            我覺得你這個(gè)例子并不說明什么
            這個(gè)例子就是通常的單件模式的使用情形。

            1、它沒有避免全局變量的弊端。對(duì)結(jié)構(gòu)不太注意的人隨時(shí)可以Singleton::GetInstance();

            2、如果它要單一實(shí)例,那么這里肯定有一個(gè)內(nèi)在因素。一個(gè)比較通常的情況是,這個(gè)類是一個(gè)框架(或某個(gè)框架的一部分)。既然它是框架,那么框架本身自然可以將其隱藏,或者以本框架最頭條使用說明的方式明令禁止實(shí)例化。如MFC的CWinApp,如果有人實(shí)例化2個(gè)CWinApp導(dǎo)致錯(cuò)誤,一定是那個(gè)人太小白了而不是MFC太傻;類似的可能還有NTService的封裝。除此之外可能還有些啥原因我一時(shí)羅列不出來。

            3、如果它要被多個(gè)局部共享,那么這實(shí)際上就是赤果果的全局變量,用了就用了,沒必要假裝沒用過


            至于get和set,我現(xiàn)在還不知道自己感覺到底如何。至少我認(rèn)為不是所有的都需要public出來的。最多,給所有非隱藏變量個(gè)get,給所有非只讀公開變量來個(gè)set就差不多了吧。

              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 14:26 | yrj
            @溪流
            一組全局函數(shù)如果一定要完全OOP則可以封裝到“靜態(tài)類”里面:

            靜態(tài)類沒必要
            namespace AAA
            {
            void foo();
            void bar();

            //...

            } // namespace AAA  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 14:32 | 溪流
            @yrj

            我是說,如果要滿足形式上的OOP  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 14:58 | 遠(yuǎn)古毛利人
            我覺得單件模式給庫作者使用比較好,因?yàn)殪o態(tài)數(shù)據(jù)沒法避免用戶多次定義。
            單件的話因?yàn)殚L(zhǎng)得顯眼,用戶一看就知道。
            另外,在GetInstance()里也可以做一些復(fù)雜的初始化動(dòng)作,呵呵。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 15:03 | gbb21
            鑒于溪流GG的blog上了我的google reader,于是特來YM  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要?[未登錄] 2010-03-29 15:16 | chentan
            用C的思維去思考,就沒有那么多思想負(fù)擔(dān)了  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 15:45 | 矩陣操作
            @遠(yuǎn)古毛利人
            同意你這個(gè)看法。C++里面單件形式意義大于實(shí)際意義。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 15:47 | 空明流轉(zhuǎn)
            @溪流
            設(shè)計(jì)模式的目標(biāo)在兩個(gè)方面:
            一個(gè)方面是給你一點(diǎn)你需要的自由,第二個(gè)是不給你除了給你的自由以外的東西。

            某種意義上,Singleton是最好的用例。至于Singleton的實(shí)現(xiàn),有很多種。
            VCZH提供的,也是一種實(shí)現(xiàn)。

            我看了一下樓上的評(píng)論,似乎都狹隘的將Singleton局限在Class::Instance()這樣的GOF標(biāo)準(zhǔn)里面了。
            但是實(shí)際上不盡然。特別是橫跨Binary的,或者是C-Compatible的設(shè)計(jì),都一定是GetXXX()這樣一個(gè)自由函數(shù)的實(shí)現(xiàn)。

            所以討論Singleton模式,并不只是討論實(shí)現(xiàn),更重要的,是討論兩點(diǎn),也就是我最初提到的兩點(diǎn):

            第一,一個(gè)類型實(shí)例數(shù)量的限制;
            第二,訪問感知性(比方說如果我是GetInstance的時(shí)候,我每次訪問都可以明明白白的追蹤到訪問點(diǎn)。而Global就比較困難,有時(shí)候你很難知道變量在什么時(shí)候被修改了。)  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 16:33 | 溪流
            @空明流轉(zhuǎn)
            前面的論述我基本上接受,但最后兩點(diǎn)還是想不通

            比如第二點(diǎn),我要知道他什么時(shí)候被修改了,如果用的是全局變量,我可能要全工程搜索變量名字,如果是單件模式,我可能要全工程搜索XXX::GeInstance(),這一點(diǎn)我看不出單件模式帶來的任何好處  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 16:34 | OwnWaterloo
            @空明流轉(zhuǎn)
            >>都一定是GetXXX()這樣一個(gè)自由函數(shù)的實(shí)現(xiàn)

            這沒錯(cuò)。 而且還要區(qū)分2種語意:
            1.
            xxx_init
            ...
            xxx_get

            2.
            xxx_get_and_init
            第2種語意我不喜歡。


            將xxx_get, xxx_init搞成xxx::instance完全是脫了褲子放屁。
            本身就是一個(gè)free function的事情, 非要搞出個(gè)class出來。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要?[未登錄] 2010-03-29 16:51 | 清風(fēng)
            @溪流
            遇到這種情況,難道你不是在GetInstance函數(shù)里檢測(cè)被修改的時(shí)機(jī)嗎.....?  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 17:23 | 唐榮軍
            你已經(jīng)進(jìn)步了,等哪次你覺得它還是有必要的時(shí)候,就表明你更進(jìn)一步了。祝好運(yùn)!  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 17:26 | 空明流轉(zhuǎn)
            @溪流
            斷點(diǎn),謝謝。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 19:53 | 陳梓瀚(vczh)
            @OwnWaterloo
            1:堅(jiān)持所有singleton都必須在main之前自動(dòng)初始化完成
            2:堅(jiān)持singleton之間不能有任何使用關(guān)系
            3:因此不需要XX_init,get就好了  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 20:05 | OwnWaterloo
            @陳梓瀚(vczh)
            main之前自動(dòng)初始化也是需要代碼的。

            C++的運(yùn)行庫會(huì)幫忙做這個(gè)事情。而C不行。 至少標(biāo)準(zhǔn)C不行。
            編譯器提供的DllMain或者 __atrribute__(constructor)啥啥的不算。

            所以, C里面init是需要的。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-29 22:10 | 空明流轉(zhuǎn)
            @陳梓瀚(vczh)
            這種堅(jiān)持通常都頗具難度。。。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要?[未登錄] 2010-03-30 09:28 | hh
            不去老老實(shí)實(shí)坐點(diǎn)業(yè)務(wù) 討論這個(gè)有1毛的意義嗎?

              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 09:53 | Iloveprogram
            @陳梓瀚(vczh)
            剛學(xué)singleton的時(shí)候,也是為那些個(gè)多線程不安全的問題煩惱過。后來一想何必那么麻煩,在使用以前實(shí)例化好就得了,使用的時(shí)候直接get。這樣性能又好,又簡(jiǎn)潔。
            看到大師也有這種觀點(diǎn),很是欣慰,呵呵。

            btw,對(duì)你現(xiàn)在在做的東西很感興趣,不過我自己水平未到。

              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 09:59 | 溪流
            @hh
            你如果覺得沒意義,大可不必來此浪費(fèi)時(shí)間,謝謝!  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 10:01 | 溪流
            @唐榮軍
            我喜歡你的這種口氣,但希望知道你的具體內(nèi)容,不然這樣的話我也會(huì)說  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 10:01 | 溪流
            @空明流轉(zhuǎn)
            好的!這算單件模式一個(gè)優(yōu)點(diǎn)吧。。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 10:25 | holyfire
            單件可以在設(shè)計(jì)時(shí)就考慮到自己是唯一的實(shí)例,但是用全局對(duì)象有幾個(gè)問題,

            1:對(duì)象可能產(chǎn)生多個(gè)實(shí)例,如果你的類隱藏的數(shù)據(jù)成員可能被構(gòu)造函數(shù)修改的話,提供者就會(huì)失去控制權(quán)。比如一個(gè)不小心使用了值參數(shù)導(dǎo)致臨時(shí)對(duì)象被構(gòu)造。

            2:如果有代碼在main前面執(zhí)行的話有初始化順序問題

            3:如果這個(gè)單件是個(gè)基類指針,單件可以在運(yùn)行時(shí)配置并保證多線程安全

            4:如果這個(gè)單件在DLL中并會(huì)被重新加載,單件模式更方便使用

            5:?jiǎn)渭J胶腿肿兞肯啾容^只是書寫習(xí)慣的問題

            那么,如果你的要求很簡(jiǎn)單并沒有涉及到以上問題(可能還有一些問題我沒發(fā)現(xiàn)),那么全局變量的確可以滿足你的要求。

            很多人都覺得main之前初始化單件很容易,那是你工作的內(nèi)容面還不夠廣,很多方面會(huì)導(dǎo)致你的代碼在main前面執(zhí)行而且是你不知道的情況下,比如DLL的靜態(tài)鏈接庫方式使用,使用第3方庫,比如ACE會(huì)修改main宏替換自己的main函數(shù),或者你的代碼本身就在DLL中。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 11:20 | 空明流轉(zhuǎn)
            @holyfire
            Ace在工程上,就是一坨屎。。。完全沒法用。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:52 | 陳梓瀚(vczh)
            @OwnWaterloo
            不管要不要代碼初始化,只要你堅(jiān)持所有不同的singleton對(duì)象都不需要依賴于其他singleton對(duì)象來創(chuàng)建那么就沒有問題。如果不行,那么證明設(shè)計(jì)有錯(cuò),或者沒錯(cuò)但是很難實(shí)現(xiàn),或者沒錯(cuò)很容易實(shí)現(xiàn)但是很容易寫出bug,總之要改。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:53 | 陳梓瀚(vczh)
            @hh
            你要是能把你做的業(yè)務(wù)寫到博客,看公司開不開你啦  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:53 | 陳梓瀚(vczh)
            @空明流轉(zhuǎn)
            控制大工程需要使用一些可能會(huì)造成開發(fā)起來有一點(diǎn)點(diǎn)麻煩,但是從根本上排除了很多bug的根源的方法。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:55 | 陳梓瀚(vczh)
            @OwnWaterloo
            用一種語言去表達(dá)一些概念,如果造成不可消除的重復(fù)代碼或模式的話,那么應(yīng)該在可能的情況下更換語言。舉個(gè)例子,你為PC開發(fā)軟件,那么C完全沒必要,C++能兼容它。因此你可以引入一點(diǎn)點(diǎn)C++的特征去消除你的困難,剩下的你愛用C寫就用C寫。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:55 | 陳梓瀚(vczh)
            @Iloveprogram
            要以發(fā)展的眼光看問題。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:56 | 陳梓瀚(vczh)
            @OwnWaterloo
            話說回來,只要保持singleton必須在main前構(gòu)造完畢這個(gè)原則的話,就算你singleton的創(chuàng)建互相依賴,也是不需要鎖的。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 15:58 | 陳梓瀚(vczh)
            @holyfire
            那證明你把不該singleton的東西給singleton了,應(yīng)該修改設(shè)計(jì),而不是想辦法實(shí)現(xiàn)singleton。

            舉個(gè)簡(jiǎn)單的例子,我可能需要在很多地方使用相同的正則表達(dá)式,那么每次都寫regex(L"....") r;顯然是浪費(fèi)了構(gòu)造時(shí)間的,所以這可能就會(huì)被放在一個(gè)全局的地方。那你說應(yīng)不應(yīng)該做成singleton呢?顯然是不需要的,你需要的是把你這些regex放在一個(gè)Context類里面,在main函數(shù)創(chuàng)建,然后傳遞給所有其他對(duì)象。

            還有,一個(gè)類是否應(yīng)該成為singleton,不是類自己決定的,而是使用類的那個(gè)人決定的。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 16:05 | OwnWaterloo
            @陳梓瀚(vczh)
            >>用一種語言去表達(dá)一些概念,如果造成不可消除的重復(fù)代碼或模式的話,那么應(yīng)該在可能的情況下更換語言。

            只所以要說C:
            1. 上面提到了C
            2. C++做二進(jìn)制兼容的東西很煩

            而且, 如果不了解C++在初始化靜態(tài)對(duì)象時(shí)做了哪些工作, 就會(huì)犯錯(cuò)。
            比如, 很多人都覺得C++靜態(tài)對(duì)象初始化是線程安全的, 其實(shí)是和實(shí)現(xiàn)相關(guān)的。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 16:12 | OwnWaterloo
            @陳梓瀚(vczh)
            >>不管要不要代碼初始化,只要你堅(jiān)持所有不同的singleton對(duì)象都不需要依賴于其他singleton對(duì)象來創(chuàng)建那么就沒有問題。如果不行,那么證明設(shè)計(jì)有錯(cuò),或者沒錯(cuò)但是很難實(shí)現(xiàn),或者沒錯(cuò)很容易實(shí)現(xiàn)但是很容易寫出bug,總之要改。

            你說得也太武斷了。 設(shè)計(jì)有問題?
            總有東西的初始化需要申請(qǐng)內(nèi)存, 能不依賴C heap和C++ free store?

            初始化后有部分東西又需要向atexit注冊(cè), 又依賴另一個(gè)全局的東西。
            初始化失敗, 有部分人喜歡寫log(雖然我不喜歡), 再次依賴全局的東西。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 16:14 | OwnWaterloo
            @陳梓瀚(vczh)
            >>話說回來,只要保持singleton必須在main前構(gòu)造完畢這個(gè)原則的話,就算你singleton的創(chuàng)建互相依賴,也是不需要鎖的。

            class evil
            {
            evil()
            {
            pthread_create(... );
            _beginthreadex( ... );
            }
            };

            如果這個(gè)例子確實(shí)太邪惡, 別忘了還有可能會(huì)碰見進(jìn)程共享數(shù)據(jù)。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 17:57 | holyfire
            @陳梓瀚(vczh)
            雖然看不明白你想對(duì)我表達(dá)什么,或者是找錯(cuò)人了?不過感覺你有點(diǎn)想當(dāng)然了,好像人人都該像你規(guī)定的那樣去做,不過我遇到的問題大多是是工作上實(shí)際遇到事,而你說的那個(gè)例子更像是用原型模式(Prototype)的情況,當(dāng)然不應(yīng)該作為單件模式,而且我并沒有舉例子說什么什么情況下該用單件模式,而是說遇到某種情況用單件模式比全局對(duì)象好,麻煩你看仔細(xì)點(diǎn)。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 18:50 | 溪流
            到后面我都看不大懂了~~~
            搬張凳子學(xué)習(xí)了,各位大俠請(qǐng)繼續(xù)~  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 22:25 | 陳梓瀚(vczh)
            @OwnWaterloo
            1:初始化的時(shí)候連內(nèi)存都申請(qǐng)不了應(yīng)該直接崩潰,這是最好的辦法。所以這個(gè)不是理由。

            2:main函數(shù)執(zhí)行之前沒有其他線程,不存在共享的讀取問題。如果需要啟動(dòng)線程,應(yīng)該讓singleton提供函數(shù)讓main函數(shù)執(zhí)行并啟動(dòng)。任何庫不應(yīng)該悄悄啟動(dòng)線程,除了GUI。再者,你應(yīng)該充分信任平臺(tái)API,這是唯一你不可控制的東西。

            3:singleton初始化的時(shí)候不相互依賴是一件好事,如果實(shí)在非依賴不可,那么一方面說明你可能將不應(yīng)該singleton得給singleton了,另一方面則有可能是你把本來應(yīng)該存在同一個(gè)singleton得給拆分成多個(gè)singleton了,種種設(shè)計(jì)問題帶來的非依賴不可的結(jié)果。

            4:如果一個(gè)二進(jìn)制發(fā)行的庫是你開發(fā)的話,那么不再庫里面提供singleton是一個(gè)很好的選擇。一個(gè)程序的所有singleton只能存在在exe里面。話說回來,二進(jìn)制其實(shí)不是問題,你應(yīng)該堅(jiān)持你自己的程序和庫都是用同一個(gè)編譯器編譯。如果庫沒提供二進(jìn)制,那么應(yīng)該索取代碼,是在索取不了,那么使用其他庫。作為一個(gè)庫的發(fā)行者,要么提供C++代碼,要么提供所有流行編譯器的二進(jìn)制編譯結(jié)果。這才是負(fù)責(zé)任的,除非你從一開始就不打算跨編譯器或者跨平臺(tái)(windows和linux都有主流C++編譯器)。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 22:31 | 陳梓瀚(vczh)
            @OwnWaterloo
            然后我再次強(qiáng)調(diào),一個(gè)類是否應(yīng)該當(dāng)成singleton,應(yīng)該取決于調(diào)用者而不是類自己,除非因?yàn)槠脚_(tái)的API限制(譬如說windows下面的GUI通常都會(huì)有的Application類)  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-30 22:37 | OwnWaterloo
            @陳梓瀚(vczh)
            >>初始化的時(shí)候連內(nèi)存都申請(qǐng)不了應(yīng)該直接崩潰,這是最好的辦法。所以這個(gè)不是理由。

            "申請(qǐng)不了"同"需要依賴內(nèi)存分配器已初始化" 完全是兩碼事。
            你又跑題了。

            >>任何庫不應(yīng)該悄悄啟動(dòng)線程,除了GUI

            這只是"你覺得"應(yīng)該這樣。
            但你馬上又說了一個(gè)反例。

            3. 我只想說對(duì)全局某些服務(wù)的依賴是很難避免的。
            singleton關(guān)我什么事? 我老早不用這種脫了褲子放屁的玩意了。


            >>作為一個(gè)庫的發(fā)行者,要么提供C++代碼,要么提供所有流行編譯器的二進(jìn)制編譯結(jié)果。這才是負(fù)責(zé)任的。

            作為一個(gè)二進(jìn)制庫的發(fā)布者, 將庫用C實(shí)現(xiàn)并提供C++的header-only的綁定層; 或者發(fā)布C++的源代碼。
            這才是負(fù)責(zé)任的。

            所有流行編譯器? 你知道什么叫所有流行編譯器么?
            編譯器種類×編譯器版本×編譯器運(yùn)行庫版本×你的庫版本

            你覺得你能負(fù)這個(gè)責(zé), 你就繼續(xù)玩吧。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要?[未登錄] 2010-03-31 10:42 | sun
            我想還是比較有用的,舉個(gè)例子,也是我做過的,創(chuàng)建一個(gè)singleton類,需要常鏈接到服務(wù)器,時(shí)序同步,在不同的線程間共享,非常的高效,尤其是在資源很缺乏的機(jī)器上,像iphone設(shè)備,碰到了就覺得需要了.......
            其實(shí)平時(shí)很少用!  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-31 15:40 | 陳梓瀚(vczh)
            @OwnWaterloo
            顯然“所有流行編譯器版本”是一個(gè)你只需要下載完寫了從vcproj到的makefile生成器以后就自動(dòng)完成的事情,一勞永逸也,想做當(dāng)然能做,而且隨時(shí)更新。運(yùn)行庫版本一律使用static鏈接,因此可以跟你的編譯器版本捆綁在一起。而且,編譯器的【小版本】之間的變化導(dǎo)致lib不能通行應(yīng)該歸咎于編譯器的質(zhì)量,而不是你。

            第二,反例當(dāng)然是要的,有些東西必須成為singleton,典型的GUI就是,一個(gè)程序不可能也不應(yīng)該同時(shí)使用N套平行的GUI庫(嵌套關(guān)系除外)。所以這個(gè)沒有任何問題。

            第三,main之前的任何異常都不要捕捉,任由崩潰。想log就捕捉了log,log完還是要throw;以便崩潰

            第四,二進(jìn)制發(fā)布者那一句我們兩個(gè)說法沒有任何區(qū)別

            第五,VC++里面沒有看見任何singleton在創(chuàng)建前new還不能用的,如果其他編譯器有,那是編譯器的bug,要么放棄它,要么放棄singleton。

            第六,我的所有觀點(diǎn)都從以下方面出發(fā)
            1:盡可能將bug扼殺在搖籃里
            2:制作出來的程序容易被更改  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-03-31 15:57 | OwnWaterloo
            @陳梓瀚(vczh)
            >>顯然“所有流行編譯器版本”是一個(gè)你只需要下載完寫了從vcproj到的makefile生成器以后就自動(dòng)完成的事情,一勞永逸也,想做當(dāng)然能做,而且隨時(shí)更新。

            這只是構(gòu)建腳本而已。 我說的是不同編譯器產(chǎn)生出的二進(jìn)制代碼的兼容性。
            你能用msvc鏈接到一個(gè)mingw生成的二進(jìn)制庫嗎?
            你能用msvc鏈接到前一個(gè)crt版本嗎?

            >>運(yùn)行庫版本一律使用static鏈接,因此可以跟你的編譯器版本捆綁在一起。
            看吧, 你又"一律", "一定" 什么的了。

            這是C++語言本身的問題。 C++的特性太復(fù)雜, 而且是一門開放的語言, 所以會(huì)有很多二進(jìn)制上不兼容的特性。
            而且C++這門語言本身就會(huì)促使開發(fā)者使用復(fù)雜的設(shè)計(jì)。

            >> 一個(gè)程序不可能也不應(yīng)該同時(shí)使用N套平行的GUI庫(嵌套關(guān)系除外)
            你沒見過而已。 確實(shí)有這樣的東西存在。 MFC+WTL+還有一個(gè)什么忘記了。
            當(dāng)然, 那東西確實(shí)丑陋。
            不過已經(jīng)是這樣子了, 推倒重來的代價(jià)公司受不起, 用戶也受不起。


            >>main之前的任何異常都不要捕捉,任由崩潰。想log就捕捉了log,log完還是要throw;以便崩潰
            再次強(qiáng)調(diào), "需要全局的依賴" 和 "處理全局初始化錯(cuò)誤" 是兩回事。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-01 01:46 | 沙城來客
            1.做個(gè)標(biāo)識(shí),讓人家知道這個(gè)東西是單例的 明白該怎么用 全局就沒有這種作用,不過到底怎么用是調(diào)用者的問題,不過至少自己的份內(nèi)事情要做好
            2.推遲初始化 在大系統(tǒng)里面一開始一堆全局的大類進(jìn)行初始化是很恐怖的事情  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-01 15:50 | 陳梓瀚(vczh)
            @OwnWaterloo
            如果你搞定了構(gòu)建腳本,你怎么還會(huì)有vc連接不了mingw的lib的問題呢?已經(jīng)被生成的一大堆lib搞定了,你挑一個(gè)正確的就好了。

            “C++促使程序猿使用復(fù)雜的設(shè)計(jì)”這個(gè)東西跟論點(diǎn)沒有任何關(guān)系,既然要寫庫,那么肯定會(huì)有些約束的。一律和一定跟這個(gè)沒有任何沖突。根據(jù)第一個(gè)觀點(diǎn),第一,構(gòu)建腳本好寫。第二,有了足夠的構(gòu)建腳本你就可以挑選任意種類的lib。第三,因此編譯器相同,因此可以static。因?yàn)檫@是運(yùn)行庫,運(yùn)行庫跟程序里面的功能模塊是兩回事,尺寸特別小,static沒有任何壞處,沒有static你還有機(jī)會(huì)犯錯(cuò)。

            我們并不需要照顧100%的人的需求,譬如少數(shù)公司因?yàn)闅v史原因造成的N個(gè)GUI一起使用等等(其實(shí)歷史原因跟singleton的主題并沒有什么大的關(guān)系)

            最后,我不認(rèn)為全局初始化錯(cuò)誤除了log以外應(yīng)該做其他事情。如果連初始化都沒搞定,那么顯然應(yīng)該崩潰。如果不應(yīng)該崩潰,那么那個(gè)東西就不屬于初始化的一部分,而應(yīng)該類似于“插件”,這種時(shí)候不能用singleton,而應(yīng)該用一個(gè)manager來管理這些事情。當(dāng)然manager需不需要singleton是另外一回事請(qǐng),總之是在main之后才開始做的。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-01 16:57 | OwnWaterloo
            @陳梓瀚(vczh)
            >> 一大堆lib搞定了,你挑一個(gè)正確的就好了。
            挑得出來嗎?

            你會(huì)為VC6用戶生成相應(yīng)的binary嗎?

            客戶使用了-fabi-version 怎么辦?
            客戶使用了-mno-align-double又怎么辦?

            你要規(guī)定用戶所使用的編譯參數(shù)? 你能規(guī)定用戶使用的編譯參數(shù)?
            你能確保用戶"僅僅使用你一個(gè)人的庫"?

            你想得太簡(jiǎn)單了。

            >> 那么肯定會(huì)有些約束的
            這些約束會(huì)被很不經(jīng)意的打破。 很難控制住。
            因?yàn)镃++給了程序員太多可以玩, 可以炫的東西。
            所謂的"心智包袱"。

            >>尺寸特別小,static沒有任何壞處
            算了, 你總是把很有爭(zhēng)議的話說得如此絕對(duì), 我還能說你什么呢。


            而且我第3次強(qiáng)調(diào)了, 我不想討論全局初始化失敗應(yīng)該怎樣。
            你覺得應(yīng)該怎樣你可以繼續(xù)說。

            我上面舉的例子, 僅僅是為了說明對(duì)"全局的依賴很難避免"。
            我覺得已經(jīng)足夠說明了。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-02 12:25 | cexer
            把單件放在其它模式堆里,確實(shí)有點(diǎn)雞立鶴群的感覺,它并沒有其它模式那樣有啟發(fā)性,所有寫程序的人都知道世上有全局變量這個(gè)東西,那何必要取個(gè)好聽的名字像模像樣地研究一番呢,《設(shè)計(jì)模式》的偉大除了讓人學(xué)會(huì)到很多手法,還有一點(diǎn)就是統(tǒng)一了很多概念,并為之提供了許多標(biāo)準(zhǔn)的名詞方便大家研究,綜上所述,我覺得“單件”就是一個(gè)虛名,你喜歡叫它“全局變量”也行,大家心里的概念沒有差別,只是未必真是用全局變量來實(shí)現(xiàn)而已,所以不用在一個(gè)名字上糾結(jié)。

            誰不想用赤祼祼的全局指針,它們?cè)加旨儤悖烊粺o雕飾。可是真的要用它們來實(shí)現(xiàn)一份庫級(jí)別的代碼,就好像雙手拋飛刀一樣危險(xiǎn),不僅拋的人要兩眼圓睜神經(jīng)緊繃,連觀眾都要跟著捏一把冷汗。全局變量本來沒有錯(cuò),錯(cuò)的是在它們之上作出的許多美好的假設(shè),假設(shè)誰一定在誰之前產(chǎn)生,誰一定在誰之后銷毀,誰依賴著誰,誰又被誰依賴著,誰是線程安全的,誰又一定不會(huì)被多線程訪問。互相完全沒有依賴關(guān)系,不用額外控制,像終結(jié)者一樣智能,完成任務(wù)又知道自己終結(jié)的全局變量,只是個(gè)傳說。

            有很多以單件名字的手法,Meyers 單件,Alexandrescu 單件,Phoenix 單件,Schwarz 計(jì)數(shù)器,你看它們好多都叫做“單件”,但是你喜歡叫 Meyers 全局對(duì)象,Alexandrescu 全局對(duì)象,Phoenix 全局對(duì)象 也可以。

            我個(gè)人覺得,把“全局變量”拿來和“單件”相提并論是很不妥的事件。就好像拿“汽車”和“交通工具”比一樣。不是一個(gè)層面上的東西,單件也許是全局變量,也可以不是,“全局”也有多種理解角度,存儲(chǔ)位置(堆上,棧上,靜態(tài)數(shù)據(jù)區(qū)),生存區(qū)域(線程局部,進(jìn)程局部,模塊內(nèi)部),生存周期(何時(shí)生,何時(shí)死,不死)。只是“全局變量”已經(jīng)不能說明它的復(fù)雜度,但是一提“單件”大家都明白將要說的是什么,這就是“單件”存在的價(jià)值,這也是《設(shè)計(jì)模式》一書提出“單件模式”偉大所在。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-02 15:54 | OwnWaterloo
            @cexer
            用于單件的那些技術(shù), 同樣可以用于全局?jǐn)?shù)據(jù)初始化。

            C運(yùn)行庫為你初始化堆分配器, 不也不需要你多余控制?
            進(jìn)程終結(jié)后也會(huì)自己終結(jié)。
            呃, C庫不一定會(huì)真正釋放, 有可能留給OS。
            那換個(gè)例子, atexit。

            所以單件根本不是什么偉大的發(fā)明。
            只是OO時(shí)代的順應(yīng)產(chǎn)物。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-03 01:22 | cexer
            @OwnWaterloo
            我說的可能不大清楚,我的意思是“單件模式”只是一種概念,正是類似“全局?jǐn)?shù)據(jù)”這種東西的一種抽象形容,不然何以稱“模式”。拿“單件模式”和“全局?jǐn)?shù)據(jù)”本身比,是沒有可比性的,一為抽象,一個(gè)具體,一為模式,一為實(shí)例。它跟OO也沒有關(guān)系,一個(gè)C全局裸指針,也是一份單件的實(shí)體。所以不要再比來比去的了。

              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-03 19:51 | OwnWaterloo
            @cexer
            在我看來恰恰相反, 全局?jǐn)?shù)據(jù)與用戶之間的交互形式有若干, 而單件只是其中一種。
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-04 09:53 | hello
            全局變量可以實(shí)現(xiàn)單件模式的功能,但是單件模式可以避免生成多個(gè)該類型的對(duì)象
              回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-10 13:21 | 螞蟻終結(jié)者
            還是要看實(shí)際情況,并不是任何時(shí)候都可以用全局變量替代單例的。
            如在Symbian C++ S60V3以前,是不允許WSD數(shù)據(jù)(全局變量)存在的,這種情況下必須用Tls Singleton這樣的模式。。。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2010-04-10 15:08 | tangxinfa
            單件模式較之全局變量(對(duì)象)的一些優(yōu)點(diǎn):
            1,防止用戶構(gòu)造出另一個(gè)對(duì)象,這也就是為什么稱之為單件。
            將構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)私有化,而只能通過getInstance()接口獲得唯一的實(shí)例。
            2,延遲創(chuàng)建對(duì)象。
            只有用到的時(shí)候才會(huì)創(chuàng)建對(duì)象,防止程序啟動(dòng)時(shí)間過長(zhǎng),不做無用功。
            3,全局變量就夠用了,但感覺以后會(huì)需要之前兩點(diǎn)特性。
            4,全局變量命名上抓狂了:g_xxxxxxxx,globalXXXXXXXX,想來想去還不如:CXXXXXXXXXX::getInstance()夠直白。
            5,調(diào)試時(shí)好設(shè)斷點(diǎn)。  回復(fù)  更多評(píng)論
              
            # re: 討論:?jiǎn)渭J降膬?yōu)點(diǎn)何在?有無存在的必要? 2015-05-22 16:35 | lurenjia
            @陳梓瀚(vczh)
            輪子哥。。  回復(fù)  更多評(píng)論
              
            精品久久亚洲中文无码| 久久精品三级视频| 国产精品久久国产精麻豆99网站| 国产精品一久久香蕉国产线看观看| 成人资源影音先锋久久资源网| 国产综合成人久久大片91| 欧美亚洲国产精品久久高清| 久久久久免费看成人影片| 久久久久久久99精品免费观看| 香蕉aa三级久久毛片| 久久ZYZ资源站无码中文动漫| 国产亚洲成人久久| 无码国内精品久久人妻| 久久e热在这里只有国产中文精品99| 少妇无套内谢久久久久| 日韩精品国产自在久久现线拍| 亚洲欧美一级久久精品| 久久国产精品久久精品国产| 久久久久久精品免费免费自慰| 99久久免费只有精品国产| 久久天天躁狠狠躁夜夜avapp| 91久久成人免费| 久久久久亚洲AV无码专区体验| 久久久久国色AV免费观看| 99久久免费国产精品热| 国产香蕉久久精品综合网| 国产99久久久国产精免费| 五月丁香综合激情六月久久| 久久人人爽人人爽人人片AV麻豆 | 国产99久久久国产精品小说| 九九99精品久久久久久| 无码国产69精品久久久久网站| 亚洲欧美久久久久9999| 久久精品国产72国产精福利| 久久伊人精品青青草原高清| 国产人久久人人人人爽| 亚洲精品无码久久一线| 伊人精品久久久久7777| 日本精品久久久久影院日本| 久久久久亚洲AV综合波多野结衣| 久久久久久综合一区中文字幕 |