• <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>
            春暖花開(kāi)
            雪化了,花開(kāi)了,春天來(lái)了
            posts - 149,comments - 125,trackbacks - 0

            發(fā)現(xiàn)許久沒(méi)有來(lái)園子里逛了,一來(lái)是工作了,的確很忙,二來(lái)是手的確有點(diǎn)懶。想寫(xiě)點(diǎn)東西,找來(lái)找去,還是對(duì)這個(gè)園子有感情。

            最近發(fā)現(xiàn)懶惰真的是一個(gè)很容易養(yǎng)成的習(xí)慣,它會(huì)慢慢吞噬掉一切。就項(xiàng)目而言,壓力的確比學(xué)生時(shí)要繁重許多,但條理性似乎更加重要。隨手記下,隨時(shí)總結(jié)總歸是好的,一個(gè)回頭,就不知道什么是時(shí)候是個(gè)頭了。

            所以半年多的經(jīng)驗(yàn)來(lái)看,一定要及時(shí)的總結(jié)項(xiàng)目,要把最新鮮的,最熱氣騰騰的東西記錄下來(lái)。
            對(duì)自己回顧是一個(gè)幫助,對(duì)他人入門(mén)也是個(gè)捷徑。

            養(yǎng)成及時(shí)總結(jié)的習(xí)慣很重要。

            posted @ 2010-11-16 23:34 Sandy 閱讀(371) | 評(píng)論 (0)編輯 收藏
            今天是一個(gè)非常開(kāi)心的日子,我拿到了我夢(mèng)寐以求的一家公司的offer,可以繼續(xù)沿著夢(mèng)想的道路繼續(xù)前進(jìn),開(kāi)心。

            首先感謝默默支持我的人,在這一路尋找的路上,有過(guò)很多挫折,謝謝他們給我的力量,讓我越挫越勇。

            其次感謝一次次面試中給了我很多幫助的面試官,其實(shí)面試是一個(gè)互相學(xué)習(xí)的機(jī)會(huì),而且每一次的肯定都是對(duì)能力的一種肯定,給了我很多信心。最后可能由于各種原因,與一些公司擦肩而過(guò),也衷心祝愿這些公司的發(fā)展越來(lái)越好。

            最后感謝給了我很多建議的人,讓我一路堅(jiān)持夢(mèng)想的走下來(lái)。 軟件開(kāi)發(fā),是我熱愛(ài)的一個(gè)方向,我也希望能夠沿著這條路繼續(xù)走下去。






            小小廣告,如果你的網(wǎng)絡(luò)很慢,不妨試試Opera的Turbo加速,不一般的體驗(yàn)啊!
            posted @ 2009-12-21 22:29 Sandy 閱讀(512) | 評(píng)論 (3)編輯 收藏
            摘自:
            http://liuaigui.blog.sohu.com/86494742.html

            線(xiàn)程安全的(Thread-Safe):如果一個(gè)函數(shù)在同一時(shí)刻可以被多個(gè)線(xiàn)程安全地調(diào)用,就稱(chēng)該函數(shù)是線(xiàn)程安全的。線(xiàn)程安全函數(shù)解決多個(gè)線(xiàn)程調(diào)用函數(shù)時(shí)訪(fǎng)問(wèn)共享資源的沖突問(wèn)題。

            可重入(Reentrant):函數(shù)可以由多于一個(gè)線(xiàn)程并發(fā)使用,而不必?fù)?dān)心數(shù)據(jù)錯(cuò)誤。可重入函數(shù)可以在任意時(shí)刻被中斷,稍后再繼續(xù)運(yùn)行,不會(huì)丟失數(shù)據(jù)。可重入性解決函數(shù)運(yùn)行結(jié)果的確定性和可重復(fù)性。可重入函數(shù)編寫(xiě)規(guī)范為:
            1、不在函數(shù)內(nèi)部使用靜態(tài)或全局?jǐn)?shù)據(jù)
            2、不返回靜態(tài)或全局?jǐn)?shù)據(jù),所有數(shù)據(jù)都由函數(shù)的調(diào)用者提供。
            3、使用本地?cái)?shù)據(jù),或者通過(guò)制作全局?jǐn)?shù)據(jù)的本地拷貝來(lái)保護(hù)全局?jǐn)?shù)據(jù)。
            4、如果必須訪(fǎng)問(wèn)全局變量,利用互斥機(jī)制來(lái)保護(hù)全局變量。
            5、不調(diào)用不可重入函數(shù)。

            兩者之間的關(guān)系:
            1、一個(gè)函數(shù)對(duì)于多個(gè)線(xiàn)程是可重入的,則這個(gè)函數(shù)是線(xiàn)程安全的。
            2、一個(gè)函數(shù)是線(xiàn)程安全的,但并不一定是可重入的。
            3、可重入性要強(qiáng)于線(xiàn)程安全性。

            比如:strtok函數(shù)是既不可重入的,也不是線(xiàn)程安全的。加鎖的strtok不是可重入的,但線(xiàn)程安全。而strtok_r既是可重入的,也是線(xiàn)程安全的

            之所以會(huì)去查這個(gè)問(wèn)題,是在考試中遇到過(guò)考strtok這個(gè)問(wèn)題是否可用于多線(xiàn)程。自己從使用的角度上感覺(jué)不安全,但是究其原因卻不是很明白。查了一下,居然涉及到函數(shù)的線(xiàn)程安全。

            在另一篇博文中,是這樣解釋的:
            strtok不是一個(gè)線(xiàn)程安全的函數(shù)。因?yàn)楦鶕?jù)其定義,它必須使用內(nèi)部靜態(tài)變量來(lái)記錄字符串中下一個(gè)需要解析的標(biāo)記的當(dāng)前位置。但是,由于指示這個(gè)位置的變量只有一個(gè),那么,在同一個(gè)程序中出現(xiàn)多個(gè)解析不同字符串的strtok調(diào)用時(shí),各自的字符串的解析就會(huì)互相干擾。(摘自: http://hi.baidu.com/pigfanfan/blog/item/72816c958d63e743d1135ebf.html

            怎么避免呢?
            我們可以利用另一個(gè)函數(shù):strtok_r,這個(gè)是一個(gè)線(xiàn)程安全的函數(shù)——strtok_r,以此來(lái)代替strtok。
            posted @ 2009-10-22 17:33 Sandy 閱讀(1605) | 評(píng)論 (0)編輯 收藏
             轉(zhuǎn):C++ pair用法
            摘自:http://hi.baidu.com/lucene1983/blog/item/83bb68351d12ffbed1a2d3fe.html

            1 pair的應(yīng)用

            pair是將2個(gè)數(shù)據(jù)組合成一個(gè)數(shù)據(jù),當(dāng)需要這樣的需求時(shí)就可以使用pair,如stl中的map就是將key和value放在一起來(lái)保存。另一個(gè)應(yīng)用是,當(dāng)一個(gè)函數(shù)需要返回2個(gè)數(shù)據(jù)的時(shí)候,可以選擇pair。 pair的實(shí)現(xiàn)是一個(gè)結(jié)構(gòu)體,主要的兩個(gè)成員變量是first second 因?yàn)槭鞘褂胹truct不是class,所以可以直接使用pair的成員變量。

            2 make_pair函數(shù)

            template pair make_pair(T1 a, T2 b) { return pair(a, b); }

            很明顯,我們可以使用pair的構(gòu)造函數(shù)也可以使用make_pair來(lái)生成我們需要的pair。 一般make_pair都使用在需要pair做參數(shù)的位置,可以直接調(diào)用make_pair生成pair對(duì)象很方便,代碼也很清晰。 另一個(gè)使用的方面就是pair可以接受隱式的類(lèi)型轉(zhuǎn)換,這樣可以獲得更高的靈活度。靈活度也帶來(lái)了一些問(wèn)題如:

            std::pair<int, float>(1, 1.1);

            std::make_pair(1, 1.1);

            是不同的,第一個(gè)就是float,而第2個(gè)會(huì)自己匹配成double。

            以上是從網(wǎng)上找來(lái)的資料,我又查了一下關(guān)于pair的定義,其定義是一個(gè)模板結(jié)構(gòu)。
               

                    // TEMPLATE STRUCT pair
            template<class _Ty1,
                
            class _Ty2> struct pair
                
            {    // store a pair of values
                typedef pair<_Ty1, _Ty2> _Myt;
                typedef _Ty1 first_type;
                typedef _Ty2 second_type;

                pair()
                    : first(_Ty1()), second(_Ty2())
                    
            {    // construct from defaults
                    }


                pair(
            const _Ty1& _Val1, const _Ty2& _Val2)
                    : first(_Val1), second(_Val2)
                    
            {    // construct from specified values
                    }


                template
            <class _Other1,
                    
            class _Other2>
                    pair(
            const pair<_Other1, _Other2>& _Right)
                    : first(_Right.first), second(_Right.second)
                    
            {    // construct from compatible pair
                    }


                
            void swap(_Myt& _Right)
                    
            {    // exchange contents with _Right
                    std::swap(first, _Right.first);
                    std::swap(second, _Right.second);
                    }


                _Ty1 first;    
            // the first stored value
                _Ty2 second;    // the second stored value
                }
            ;

            make_pair同樣也是一個(gè)模板函數(shù)。其定義如下:
            template<class _Ty1,
                
            class _Ty2> inline
                pair
            <_Ty1, _Ty2> make_pair(_Ty1 _Val1, _Ty2 _Val2)
                
            {    // return pair composed from arguments
                return (pair<_Ty1, _Ty2>(_Val1, _Val2));
                }

            posted @ 2009-10-15 11:09 Sandy 閱讀(12054) | 評(píng)論 (0)編輯 收藏

            有這么一個(gè)關(guān)于虛函數(shù)和虛繼承的問(wèn)題,如下:
            class A
            {
                char k[3];
            public:
                virtual void aa();
            };

            class B: public virtual A
            {
                char j[3];
            public:
                virtual void bb();
            };

            class C: public virtual B
            {
                char i[3];
            public:
               virtual void cc();
            };
            請(qǐng)問(wèn)sizeof(A), sizeof(B), sizeof(C)分別為多少?

            對(duì)于A, 我們很清楚的知道,其大小為8。
            對(duì)于B,考慮到虛繼承和自身的虛函數(shù),我們也可以算出來(lái)起大小為8+8+4 = 20
            對(duì)于C,其大小為20+8+4 = 32。
            其中 4為虛繼承所占用的指針。

            這個(gè)看上去沒(méi)有什么問(wèn)題。但是當(dāng)我把虛繼承去掉以后,這里卻有了一些變化?
            首先,我猜想了一下,A是8,B是16,C是24。
            可惜結(jié)果和我想的不一樣,答案是8, 12, 16。很有規(guī)律的一個(gè)數(shù)字。
            從A到B,只增加了4。什么原因呢?

            http://www.diybl.com/course/3_program/c++/cppjs/2007927/74925.html這里介紹了一些

            The existence of virtual function(s)

            Existence of virtual function(s) will add 4 bytes of virtual table pointer in the class, which will be added to size of class. Again, in this case, if the base class of the class already has virtual function(s) either directly or through its base class, then this additional virtual function won't add anything to the size of the class. Virtual table pointer will be common across the class hierarchy. That is

            class Base {

            public:

             ...        

            virtual void SomeFunction(...);

            private:  

            int iAMem

            };

            class Derived : public Base

            {

             ...       

             virtual void SomeOtherFunction(...);

            private:      

            int iBMem

            };

            In the example above, sizeof(Base) will be 8 bytes--that is sizeof(int iAMem) + sizeof(vptr). sizeof(Derived) will be 12 bytes, that is sizeof(int iBMem) + sizeof(Derived). Notice that the existence of virtual functions in class Derived won't add anything more. Now Derived will set the vptr to its own virtual function table.


            派生類(lèi)和基類(lèi)擁有相同的虛函數(shù)表。

            但似乎虛繼承的時(shí)候,又?jǐn)P棄了這一做法。

            所以?xún)蓚€(gè)是有所區(qū)別的。

            posted @ 2009-10-07 22:43 Sandy 閱讀(1970) | 評(píng)論 (2)編輯 收藏

            今天在看面試寶典,注意到上面所說(shuō)浮點(diǎn)數(shù)在內(nèi)存里和整數(shù)的存儲(chǔ)方式不同,但究竟有何不同呢?
            在網(wǎng)上搜了一下:
            http://blog.csdn.net/djsl6071/archive/2007/03/16/1531336.aspx中介紹了浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式,覺(jué)得不錯(cuò),轉(zhuǎn)過(guò)來(lái)。

            浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式

            浮點(diǎn)數(shù)保存的字節(jié)格式如下:

            地址        +0          +1           +2           +3
            內(nèi)容    SEEE EEEE   EMMM MMMM    MMMM MMMM    MMMM MMMM

            這里
            S 代表符號(hào)位,1是負(fù),0是正
            E 偏移127的冪,二進(jìn)制階碼=(EEEEEEEE)-127。
            M 24位的尾數(shù)保存在23位中,只存儲(chǔ)23位,最高位固定為1。此方法用最較少的位數(shù)實(shí)現(xiàn)了
            較高的有效位數(shù),提高了精度。

            零是一個(gè)特定值,冪是0 尾數(shù)也是0。

            浮點(diǎn)數(shù)-12.5作為一個(gè)十六進(jìn)制數(shù)0xC1480000保存在存儲(chǔ)區(qū)中,這個(gè)值如下:
            地址 +0     +1     +2     +3
            內(nèi)容0xC1   0x48   0x00   0x00

            浮點(diǎn)數(shù)和十六進(jìn)制等效保存值之間的轉(zhuǎn)換相當(dāng)簡(jiǎn)單。下面的例子說(shuō)明上面的值-12.5如何轉(zhuǎn)
            換。
            浮點(diǎn)保存值不是一個(gè)直接的格式,要轉(zhuǎn)換為一個(gè)浮點(diǎn)數(shù),位必須按上面的浮點(diǎn)數(shù)保存格式表
            所列的那樣分開(kāi),例如:

            地址       +0           +1            +2            +3
            格式   SEEE EEEE    EMMM MMMM     MMMM MMMM     MMMM MMMM
            二進(jìn)制  11000001     01001000      00000000      00000000
            十六進(jìn)制   C1           48            00            00

            從這個(gè)例子可以得到下面的信息:
              符號(hào)位是1 表示一個(gè)負(fù)數(shù)
              冪是二進(jìn)制10000010或十進(jìn)制130,130減去127是3,就是實(shí)際的冪。
              尾數(shù)是后面的二進(jìn)制數(shù)10010000000000000000000
            在尾數(shù)的左邊有一個(gè)省略的小數(shù)點(diǎn)和1,這個(gè)1在浮點(diǎn)數(shù)的保存中經(jīng)常省略,加上一個(gè)1和小數(shù)
            點(diǎn)到尾數(shù)的開(kāi)頭,得到尾數(shù)值如下:
            1.10010000000000000000000

            接著,根據(jù)指數(shù)調(diào)整尾數(shù).一個(gè)負(fù)的指數(shù)向左移動(dòng)小數(shù)點(diǎn).一個(gè)正的指數(shù)向右移動(dòng)小數(shù)點(diǎn).因?yàn)?br>指數(shù)是3,尾數(shù)調(diào)整如下:
            1100.10000000000000000000

            結(jié)果是一個(gè)二進(jìn)制浮點(diǎn)數(shù),小數(shù)點(diǎn)左邊的二進(jìn)制數(shù)代表所處位置的2的冪,例如:1100表示
            (1*2^3)+(1*2^2)+(0*2^1)+(0*2^0)=12。
            小數(shù)點(diǎn)的右邊也代表所處位置的2的冪,只是冪是負(fù)的。例如:.100...表示(1*2^(-1))+
            (0*2^(-2))+(0*2^(-2))...=0.5。
            這些值的和是12.5。因?yàn)樵O(shè)置的符號(hào)位表示這數(shù)是負(fù)的,因此十六進(jìn)制值0xC1480000表示-
            12.5。

            關(guān)于多字節(jié)數(shù)據(jù)類(lèi)型在內(nèi)存中的存儲(chǔ)問(wèn)題


            int ,short 分別是4、2字節(jié)。他們?cè)趦?nèi)存中的存儲(chǔ)方式下面舉個(gè)例子說(shuō)明。

            int data = 0xf4f3f2f1;
            其中低位存放在編址小的內(nèi)存單元,高位存放在編址高的內(nèi)存單元
            如下:
            地址:0x8000      0x8001    0x8002   0x8003
            數(shù)據(jù):   f1              f2            f3          f4
            根據(jù)IEEE在1985年制定的標(biāo)準(zhǔn)來(lái)處理浮點(diǎn)數(shù)
            單精度浮點(diǎn)數(shù)用4字節(jié),包括1位符號(hào)位s(整數(shù)為0,負(fù)數(shù)為1),8位指數(shù)位e,23位有效位f
            浮點(diǎn)型使用的是科學(xué)計(jì)數(shù)法,比如十進(jìn)制的12345可以表示為1.2345 * 10^4(表示10的4次冪)
            用二進(jìn)制表示為 1.1000000111001 * 2^13
            所以計(jì)算機(jī)中用浮點(diǎn)數(shù)表示12345這個(gè)十進(jìn)制應(yīng)該是這樣的,s位為0,因?yàn)槭钦龜?shù),指數(shù)位為13+127=140(127為單精度浮點(diǎn)數(shù)偏移值,為了表示只有小數(shù)部分的數(shù)),有效位為1000000111001
            計(jì)算的時(shí)候用 (-1)^s * 1.f * 2^(e-127) ,結(jié)果就是 1* 1.1000000111001 * 2^(140-127=13) ,和我們剛才表示的一樣
            還比如,十進(jìn)制小數(shù)0.125轉(zhuǎn)換為二進(jìn)制小數(shù)0.001可以表示為 1* 1.0 * 2^(124-127=-3)
            double,雙精度浮點(diǎn)數(shù)有1位符號(hào)位、11位指數(shù)位和52位有效數(shù)
            謝謝,和我找的資料差不多:)
            知道公式
            n=(-1)^s*m*2^e
            e=|E|-bias
            bias = 2^(k-1)-1(k為E的位數(shù))
            m=|1.M|


            知道12345在內(nèi)存中的10進(jìn)制表示以后
            0x4640e400 = 0(100 0110 0)<100 0000 1110 0100 0000>
            括號(hào)中的數(shù)字為|E| = 140 所以e=140-127=13
            尖括號(hào)中的數(shù)字為m=|1.M|=|1.100000011100100|=1.506958008
            ok,
            代入公式n = (-1)^0*1.506958008*2^13=12345
            完工!!

             

            本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/edivista/archive/2009/06/07/4248794.aspx

             

            本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/edivista/archive/2009/06/07/4248794.aspx

            posted @ 2009-10-02 20:51 Sandy 閱讀(1075) | 評(píng)論 (0)編輯 收藏

                    DLL, 動(dòng)態(tài)鏈接庫(kù), Dynamic-link library.一直以來(lái)都是Windows操作系統(tǒng)的基石。Window應(yīng)用程序編程接口提供的所有函數(shù)都包含在DLL中。其中三個(gè)最重要的DLL分別是Kernel32.dll,User32.dll,GDI32.dll。Kernel32.dll ,包含的函數(shù)用來(lái)管理內(nèi)存、進(jìn)程以及線(xiàn)程;User32.dll包含的函數(shù)用來(lái)執(zhí)行與用戶(hù)界面相關(guān)的任務(wù),如創(chuàng)建窗口和發(fā)送消息。GDI32.dll,包含的函數(shù)用來(lái)繪制圖像和顯示文字。Windows Mobile中重要的DLL是Coredll.dll.

                     Windows系統(tǒng)廣泛使用DLL,那么我們使用DLL的理由是什么?下面是在《Windows 核心編程中》摘錄的一部分:
                     一是擴(kuò)展了應(yīng)用程序的特性;
                      二是簡(jiǎn)化了項(xiàng)目的管理;
                      三是有助于節(jié)省內(nèi)存;
                      四是促進(jìn)了資源的共享;
                      五是促進(jìn)了本地化;
                     六是有助于解決平臺(tái)間的差異;
                     七是可以用于特殊目的。 
                     目前用到的地方在 節(jié)省內(nèi)存、資源共享、本地化、特殊目的。這幾個(gè)是我在項(xiàng)目中見(jiàn)過(guò)的。DLL如何使用呢?一般有兩種方法,一是隱式載入時(shí)鏈接(implicit load-time linking)和顯示運(yùn)行時(shí)鏈接(explicit run-time linking)。
                     隱式鏈接,常用的方法是將DLL的頭文件和LIB文件包含到執(zhí)行文件程序中,相應(yīng)DLL放到執(zhí)行文件對(duì)應(yīng)的目錄。基本就OK了。
                      例如:
                       DLL為MyLib.dll,其頭文件為MyLib.h, LIB文件為MyLib.lib。
                       我們?cè)趫?zhí)行文件中使用是,需要做如下操作:
                       #include "MyLib.h"
                       #pragma comment(lib, "MyLib.lib")

                       即可實(shí)現(xiàn)隱式調(diào)用,變量、函數(shù)、類(lèi)就可實(shí)現(xiàn)調(diào)用。
                       這里lib文件非常小,它并不包含任何函數(shù)或變量,它只是列出了所有被導(dǎo)出的函數(shù)和變量的變量名,具體的實(shí)現(xiàn)在dll文件中。編譯階段不包含Lib文件會(huì)出錯(cuò)的。
                     顯示鏈接,在應(yīng)用程序運(yùn)行的過(guò)程中,顯示地載入所需的DLL。
                     一般可以使用LoadLibrary和FreeLibrary來(lái)實(shí)現(xiàn)加載和卸載DLL。那么如何判斷一個(gè)DLL是否已經(jīng)被映射到了進(jìn)程的地址空間中?我們可以使用GetModuleHandle.
                      如:
                       HMODULE hInstDll = GetModuleHandle(TEXT("MyLib"));
                       if (hInstDll == NULL)
                       {
                            hInstDll = LoadLibrary(TEXT("MyLib"));
                        }
                       我們已經(jīng)知道如何顯示加載DLL,那如何顯示調(diào)用其中的變量、函數(shù)、類(lèi)呢?
                      例如在DLL中,我們有一個(gè)變量 g_nResult, 函數(shù)Add,我們?cè)趫?zhí)行程序中如何調(diào)用呢?可以利用GetProcAddress。
                       對(duì)于變量:
                       int nResult =*(int*)GetProcAddress(hInstDll, "g_nResult");
                       對(duì)于函數(shù):
                        typedef   int   (*FUNC)(int, int); 
                        FUNC pfn = (FUNC)GetProcAddress(hInstDll, "Add");

                       這是今天學(xué)習(xí)到的關(guān)于DLL的一點(diǎn)知識(shí)。
                        

            posted @ 2009-10-02 16:43 Sandy 閱讀(698) | 評(píng)論 (0)編輯 收藏
            條款四 避免不必要的默認(rèn)構(gòu)造函數(shù)

            默認(rèn)構(gòu)造函數(shù)(指沒(méi)有參數(shù)的構(gòu)造函數(shù))是指C++語(yǔ)言中,你不用傳參數(shù)就可以調(diào)用的構(gòu)造函數(shù)。構(gòu)造函數(shù)用于初始化對(duì)象,而默認(rèn)構(gòu)造函數(shù)可以在不依賴(lài)任何外部信息的情況下創(chuàng)建對(duì)象。

            在一個(gè)完美的世界里,無(wú)需任何外部信息即可創(chuàng)建對(duì)象的類(lèi)可以包含默認(rèn)構(gòu)造函數(shù),而需要額外信息來(lái)創(chuàng)建對(duì)象的類(lèi)則不包含默認(rèn)構(gòu)造函數(shù)。可是我們的世界是不完美的,所以我們必將一些額外的因素考慮在內(nèi)。特別地,如果一個(gè)類(lèi)沒(méi)有默認(rèn)構(gòu)造函數(shù),使用這個(gè)類(lèi)的時(shí)候就會(huì)有一些限制。

            沒(méi)有默認(rèn)構(gòu)造函數(shù),在三種情況下它的應(yīng)用可能會(huì)出現(xiàn)問(wèn)題:
            第一個(gè)問(wèn)題是創(chuàng)建數(shù)組的時(shí)候,通常沒(méi)有很好的辦法可以指定數(shù)組元素的構(gòu)造函數(shù)的參數(shù)。
            第二個(gè)問(wèn)題是沒(méi)有默認(rèn)構(gòu)造函數(shù)的類(lèi)他們無(wú)法作為許多基于模板的容器類(lèi)的類(lèi)型參數(shù)使用。因?yàn)橥ǔS糜趯?shí)例化模板的哪些類(lèi)型需要提供默認(rèn)構(gòu)造函數(shù)。
            第三個(gè)問(wèn)題是在有虛基類(lèi)的時(shí)候應(yīng)該提供默認(rèn)構(gòu)造函數(shù)還是不提供默認(rèn)構(gòu)造函數(shù)。沒(méi)有默認(rèn)構(gòu)造函數(shù)的虛基類(lèi)使用起來(lái)很痛苦,這是因?yàn)樘摶?lèi)的構(gòu)造函數(shù)所要求的參數(shù)必須由創(chuàng)建對(duì)象所屬的最遠(yuǎn)的派生類(lèi)所提供。

            正因?yàn)檫@些強(qiáng)加于沒(méi)有默認(rèn)構(gòu)造函數(shù)的類(lèi)上的重中限制,一些人認(rèn)為所有的類(lèi)都應(yīng)該有默認(rèn)構(gòu)造函數(shù),即使默認(rèn)構(gòu)造函數(shù)沒(méi)有足夠的信息來(lái)完全初始化一個(gè)對(duì)象。

            但是默認(rèn)構(gòu)造函數(shù)會(huì)影響類(lèi)的運(yùn)行效率,有時(shí)會(huì)使其他成員函數(shù)變得復(fù)雜。

            如果一個(gè)類(lèi)的構(gòu)造函數(shù)能夠確保所有的數(shù)據(jù)成員被正確初始化,就能避免付出一些代價(jià)。通常默認(rèn)構(gòu)造函數(shù)不提供這些保證。如果默認(rèn)構(gòu)造函數(shù)對(duì)于某些類(lèi)沒(méi)有太大意義,最好避免使用他們。這給使用這種類(lèi)加了一些限制,但是當(dāng)你使用它時(shí),它可以向你保證你能很放心地相信這個(gè)類(lèi)被正確得初始化,并且具有高效的效率。

            說(shuō)實(shí)話(huà),這一章節(jié)我看得不是很明白。
            作者在一開(kāi)始,列舉了一些沒(méi)有默認(rèn)構(gòu)造函數(shù)我們可能遇到的問(wèn)題,在這些問(wèn)題下,進(jìn)而得出默認(rèn)構(gòu)造函數(shù)所帶來(lái)的一些效率和代價(jià)困擾。看來(lái)還需要在實(shí)踐中仔細(xì)揣摩揣摩。



            posted @ 2009-09-22 13:33 Sandy 閱讀(535) | 評(píng)論 (0)編輯 收藏

            條款三 絕不要把多態(tài)應(yīng)用于數(shù)組

            繼承的一大特性是,允許你通過(guò)指向基類(lèi)的指針和引用來(lái)操縱派生類(lèi)對(duì)象。也允許通過(guò)基類(lèi)指針和引用來(lái)操縱派生類(lèi)數(shù)組。

            但是用基類(lèi)指針操縱一個(gè)包含派生類(lèi)對(duì)象的數(shù)組,就會(huì)發(fā)生各種個(gè)樣的問(wèn)題,其結(jié)果往往是不確定的。

            我根據(jù)書(shū)中的例子,寫(xiě)了一個(gè)小程序:

            #include <iostream>

            using namespace std;

            class BST
            {
            public:
                BST()
                
            {
                    i 
            = 0;
                }

                
            int i;
            }
            ;

            class BalancedBST: public BST
            {
            private:
                
            int j;
            }
            ;

            void printBSTArray(ostream& outconst BST arr[], int numElements)
            {
                
            for (int i = 0; i < numElements; i++)
                
            {
                    
            out << arr[i].i << endl;
                }

            }


            int main()
            {
                cout 
            << "BST.\n";
                BST BSTArray[
            10];
                printBSTArray(cout, BSTArray, 
            10);

                cout 
            << "BalancedBST.\n";
                BalancedBST bBSTArray[
            10];
                printBSTArray(cout, bBSTArray, 
            10);

                system(
            "pause");

                
            return 0;
            }


            其結(jié)果如下:

             

             可以看到程序并不如我們所期望的那樣,這說(shuō)明什么呢?
             arr[i],表示的是*(arr+i),但是arr+i所指向的地址偏離arr所指向的地址是i*(an object in the array)。
            因?yàn)閰?shù)被聲明為BST數(shù)組類(lèi)型,那么數(shù)組的每個(gè)元素必須是BST,那么它們的間隔也畢定是i*sizeof(BST)。如果傳入BalancedBST數(shù)組,編譯器可能就會(huì)犯錯(cuò)誤,在這種情況下,編譯器就會(huì)假定數(shù)組里每個(gè)對(duì)象的大小都和BST的大小一樣。而通常派生類(lèi)要比基類(lèi)有更多的成員變量,所以派生類(lèi)一般都比基類(lèi)對(duì)象大。所以我們就看到了如上的結(jié)果。

             試圖通過(guò)一個(gè)基類(lèi)指針刪除一個(gè)包含派生類(lèi)對(duì)象的數(shù)組,也會(huì)有同樣的問(wèn)題。

            所以不要把多臺(tái)應(yīng)用到數(shù)組上,還是很有好處的。

            posted @ 2009-09-22 11:57 Sandy 閱讀(353) | 評(píng)論 (0)編輯 收藏

            昨天想做這么一個(gè)操作,就是將文件從一個(gè)文件夾拷貝到另一個(gè)文件夾中,同時(shí)刪除源文件夾中的內(nèi)容。想著挺簡(jiǎn)單的,于是就首先使用了MoveFile。
            當(dāng)目的文件夾中,不存在文件時(shí),MoveFile成功。而當(dāng)目的文件夾包含該文件時(shí),MoveFile則調(diào)用不成功。他不支持覆蓋。所以挪動(dòng)文件,用MoveFile似乎不是首選。
            此時(shí),我想到的是DeleteAndRenameFile,
            在SDK中解釋到This function deletes the source file after it copies the content of the source file to the destination file. 拷貝源文件的內(nèi)容到目的文件,然后刪除源文件。看似符合要求,但是他要求調(diào)用該函數(shù)的時(shí)候目的文件必須存在。

            這兩個(gè)函數(shù)都不可行,結(jié)合起來(lái)到是不錯(cuò)的選擇,可以滿(mǎn)足要求。可惜我昨天沒(méi)有這么想,昨天我想到了CopyFile。
            CopyFile的原型是
            BOOL CopyFile(
              LPCTSTR lpExistingFileName,
              LPCTSTR lpNewFileName,
              BOOL bFailIfExists
            );

            最后一個(gè)參數(shù)表示當(dāng)目的文件已經(jīng)存在的時(shí)候,CopyFile調(diào)用成功還是失敗的操作。如果為False,就可以覆蓋拷貝了。

            于是我就自己寫(xiě)了一個(gè)CopyAndDel的小函數(shù)。先拷貝再刪除原來(lái)的文件。刪除文件的時(shí)候還需要考慮一下文件屬性的問(wèn)題。

            BOOL CopyAndDel(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName)
            {
                
            if (CopyFile(lpExistingFileName, lpNewFileName, FALSE))
                
            {
                    
            if (!DeleteFile(lpExistingFileName))
                    
            {
                        SetFileAttributes(lpExistingFileName, FILE_ATTRIBUTE_NORMAL);
                        
            return DeleteFile(lpExistingFileName);
                    }

                    
            return TRUE;
                }

                
            return FALSE;
            }


            這個(gè)小函數(shù)的缺陷在于還需要考慮刪除文件的屬性問(wèn)題。似乎利用MoveFile和DeleteAndRenameFile組合更好一些。

            這里總結(jié)一下:
            MoveFile 重命名一個(gè)文件或目錄,包括它所有的孩子。可對(duì)文件夾進(jìn)行操作。不過(guò)需要保證的是新文件或新文件夾不存在,否則調(diào)用失敗。
            DeleteAndRenameFile 當(dāng)拷貝源文件的內(nèi)容到目的文件后,刪除源文件。需要保證目的文件在調(diào)用前已經(jīng)存在。
            CopyFile 拷貝一個(gè)已經(jīng)存在的文件,并生成一個(gè)新的文件。不能對(duì)文件夾進(jìn)行操作。
            DeleteFile 刪除一個(gè)文件。不能刪除文件夾。該函數(shù)刪除失敗的時(shí)候,考慮一下文件的屬性問(wèn)題。
            RemoveDirectory 刪除一個(gè)空的文件夾。

             

            posted @ 2009-09-17 09:38 Sandy 閱讀(7442) | 評(píng)論 (3)編輯 收藏
            僅列出標(biāo)題  下一頁(yè)
            久久久久久久综合日本亚洲| 青青草国产97免久久费观看| 狠狠综合久久AV一区二区三区| 手机看片久久高清国产日韩| 久久综合九色综合网站| 婷婷综合久久中文字幕蜜桃三电影| 亚洲va中文字幕无码久久不卡| 99久久99久久| 伊人久久大香线蕉无码麻豆| 久久天天躁狠狠躁夜夜96流白浆| 国产叼嘿久久精品久久| 久久综合色之久久综合| 久久66热人妻偷产精品9| 久久996热精品xxxx| 久久夜色精品国产网站| 一本色道久久88综合日韩精品| 国内精品久久九九国产精品| 久久亚洲sm情趣捆绑调教| 国产一区二区精品久久凹凸| 久久久久亚洲AV成人片| 久久青青草视频| 久久久久一本毛久久久| 青青草原综合久久大伊人精品| 欧美精品久久久久久久自慰| 亚洲欧洲久久久精品| 久久久久一本毛久久久| 国产亚州精品女人久久久久久 | 国产精品毛片久久久久久久| 色婷婷综合久久久久中文字幕 | 一本大道加勒比久久综合| 亚洲国产精品无码久久| 欧美日韩精品久久免费| 偷偷做久久久久网站| 久久人人爽人人澡人人高潮AV | 亚洲欧美一区二区三区久久| 久久精品人妻一区二区三区| 亚洲国产二区三区久久| 老司机国内精品久久久久| 久久香蕉国产线看观看99| 青青草国产精品久久| 狠狠综合久久综合中文88|