• <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>

            被無(wú)視的伊謝爾倫

            雕欄玉砌應(yīng)猶在,只是朱顏改

              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              9 隨筆 :: 0 文章 :: 6 評(píng)論 :: 0 Trackbacks

            2008年7月21日 #

            轉(zhuǎn)眼已經(jīng)2008年了,留下一筆,繼續(xù)努力!!
            posted @ 2008-07-21 20:51 愛(ài)上青菜的包子 閱讀(146) | 評(píng)論 (0)編輯 收藏

            2006年11月29日 #

            首先需要確認(rèn)的是,編譯器對(duì)非虛方法使用靜態(tài)聯(lián)編,對(duì)虛方法使用動(dòng)態(tài)聯(lián)編。
            看起來(lái),在大多數(shù)情況下,動(dòng)態(tài)聯(lián)編都更好,因?yàn)樗尦绦蚰軌蜻x擇為特定類型設(shè)計(jì)的方法,這樣問(wèn)題就來(lái)了,既然動(dòng)態(tài)聯(lián)編這么好,為什么還要設(shè)計(jì)兩種類型的聯(lián)編?為什么默認(rèn)的聯(lián)編方法是靜態(tài)的而不是動(dòng)態(tài)?

            原因關(guān)鍵就在于效率。Strousstrup說(shuō)過(guò)(很經(jīng)典,呵呵):C++的指導(dǎo)原則之一是,不要為不使用的特性付出代價(jià)(內(nèi)存或處理時(shí)間)。

            因?yàn)橥ǔG闆r下,編譯器處理虛函數(shù)的方法為:給每個(gè)對(duì)象添加一個(gè)隱藏成員,該成員中保存了一個(gè)指向函數(shù)地址數(shù)組的指針(稱為虛函數(shù)表 virtual function table,vtbl)。虛函數(shù)表中存儲(chǔ)了為類對(duì)象進(jìn)行聲明的虛函數(shù)的地址。例如,基類包含一個(gè)指針,指向了基類中所有虛函數(shù)的地址表,派生類對(duì)象將包含一個(gè)指向獨(dú)立地址表的指針,如果派生類提供了虛函數(shù)的新定義,該虛函數(shù)表將保存新函數(shù)的地址,如果沒(méi)有重新定義,則保留原始版本的地址。調(diào)用虛函數(shù)時(shí),程序?qū)⒉榭创鎯?chǔ)在對(duì)象中的vtbl地址,然后轉(zhuǎn)向相應(yīng)的函數(shù)地址表。

            所以顯而易見(jiàn)的是,使用虛函數(shù)時(shí),在內(nèi)存和執(zhí)行速度方面有一定的額外成本,包括:
            每個(gè)對(duì)象都將增大,增大量為存儲(chǔ)地址的空間;對(duì)每個(gè)類,編譯器都創(chuàng)建一個(gè)虛函數(shù)地址表(數(shù)組);每個(gè)函數(shù)調(diào)用都需要執(zhí)行一步額外的操作,即到表中查找地址。

            所以咱們要養(yǎng)成的習(xí)慣是,在設(shè)計(jì)類時(shí),可能包含一些不在派生類重新定義的成員函數(shù),那么這些函數(shù)就不要設(shè)置為虛函數(shù)。這樣首先會(huì)有更好的效率,其次被聲明為虛函數(shù)的成員函數(shù)就表明是預(yù)期在派生類中會(huì)被重新定義的,在閱讀代碼時(shí)也將比較方便。
            posted @ 2006-11-29 17:27 愛(ài)上青菜的包子 閱讀(611) | 評(píng)論 (0)編輯 收藏

            2006年11月10日 #

            最近全面檢查了下身體,拿到體檢報(bào)告的時(shí)候,發(fā)現(xiàn)有一項(xiàng)血液尿酸偏高,醫(yī)生在后面批注,少食動(dòng)物內(nèi)臟。

            疑惑了一下,正準(zhǔn)備網(wǎng)上查查,結(jié)果有同事發(fā)了封公司郵件,正好是說(shuō)這個(gè)事的,貌似出現(xiàn)該情況的人也有不少。看了看內(nèi)容,如下:

            出現(xiàn)尿酸偏高的現(xiàn)象,這是酸性體質(zhì)的表現(xiàn)。是由于進(jìn)食過(guò)多高蛋白、高脂肪、高糖類美食造成的。要改變偏酸性體質(zhì),關(guān)鍵在于飲食,要多吃堿性食物。所謂食物的酸堿性,是說(shuō)食物中的無(wú)機(jī)鹽屬于酸性還是屬于堿性。一般金屬元素鈉、鈣、鎂等,在人體內(nèi)其氧化物呈堿性,含這種元素較多的食物就是堿性食物,如大豆、豆腐、菠菜、萵筍、蘿卜、土豆、藕、洋蔥、海帶、西瓜、香蕉、梨、蘋果、牛奶等。一些食物中含有較多的非金屬元素,如磷、硫、氯等,在人體內(nèi)氧化后,生成帶有陰離子的酸根,屬于酸性食物。如豬肉、牛肉、雞肉、鴨、蛋類、鯉魚、牡蠣、蝦,以及面粉、大米、花生、大麥、啤酒等。所以不要誤以為蘋果等吃起來(lái)很酸就是酸性食物,那是大錯(cuò)特錯(cuò)的,剛好相反,蘋果是一種堿性的食物。

            酸性體質(zhì),健康新殺手

            ???吃得好了,身體卻變?"酸"了
            ???"俺們那年代,缺飯又少菜;如今這年代,吃得真不賴"的確如此,現(xiàn)代人生活水平不斷在提高,每天大魚大肉,頓頓都離不開葷,年輕人去麥當(dāng)勞、肯德基吃洋快餐更是家常便飯.可是根據(jù)一項(xiàng)調(diào)查研究表明:生活水平越來(lái)越好,醫(yī)療水平越來(lái)越高,現(xiàn)代文明病卻越來(lái)越多;發(fā)病率越來(lái)越高;患者越來(lái)越年輕化。有數(shù)字顯示:我國(guó)目前的高血壓人群已達(dá)到1.6?個(gè)億,我國(guó)的高血脂人群是?6500萬(wàn),糖尿病人?4800萬(wàn)并以每年10%的速度高速增長(zhǎng),每年死于癌癥的有130?多萬(wàn)人,死于心腦血管疾病的有200?多萬(wàn)人。70年代我們國(guó)家就呼吁要讓高血壓低頭,可現(xiàn)在我們?cè)诟哐獕好媲暗土祟^。我國(guó)心臟病的發(fā)病年齡比80?年代初期整整提早了15年,也就是說(shuō)原來(lái)50歲開始得心臟病的,現(xiàn)在35歲的人就開始得心臟病。多么觸目驚心的數(shù)字,而這些數(shù)字只是官方統(tǒng)計(jì),還沒(méi)有加上未檢查出來(lái)的。我們不禁要問(wèn):這到底是怎么了?越來(lái)越多的醫(yī)學(xué)家、營(yíng)養(yǎng)學(xué)家和研究機(jī)構(gòu)為此現(xiàn)象設(shè)立課題進(jìn)行研究,最后得出一致結(jié)論:酸性體質(zhì)是病魔元兇。
            ????挖出酸性體質(zhì)的根
            ????那么酸性體質(zhì)是怎么來(lái)的呢?現(xiàn)代醫(yī)學(xué)研究向我們揭示了真相:魚肉禽蛋油米面等這些高蛋白、高脂肪、高糖類美食在為我們提供能量和營(yíng)養(yǎng)的同時(shí),也在提供大量的酸性物質(zhì)。那么到底什么物質(zhì)產(chǎn)生什么酸呢??我們一起來(lái)看看:?蛋白質(zhì)(主要來(lái)源于瘦肉、魚、蛋等)在體內(nèi)代謝產(chǎn)生含硫氨基酸、含磷氨基酸、尿酸等等;脂肪(主要來(lái)源于肥肉、油等)在體內(nèi)代謝產(chǎn)生烴丁酸、乙酰乙酸(也稱酮酸);碳水化合物(糖類,主要來(lái)源于米面)在體內(nèi)代謝產(chǎn)生甘油酸、丙酮酸、乳酸。
            ????"酸"不除,后患無(wú)窮
            ????人體攝入的酸性食物過(guò)多,超過(guò)了人體酸堿平衡的調(diào)節(jié)能力,肝腎等身體重要部位超負(fù)荷運(yùn)作,人體的酸堿平衡就會(huì)被破壞,使體內(nèi)酸堿失衡,甚至出現(xiàn)輕度酸中毒反應(yīng),這就是我們所說(shuō)的酸性體質(zhì)。
            ????其實(shí)我們?nèi)梭w就象個(gè)養(yǎng)魚的池塘,占人體體重70%的體液就是池塘里的水,水被污染了魚就要生病死亡,同樣的道理,人體體液被酸性物質(zhì)污染了,組成我們?nèi)梭w的60萬(wàn)億個(gè)細(xì)胞的生態(tài)環(huán)境就會(huì)發(fā)生變化,細(xì)胞就會(huì)發(fā)生突變和病變而影響我們的健康。我們都知道:酸性物質(zhì)沉積在肝臟中會(huì)產(chǎn)生脂肪肝;酸性物質(zhì)沉積在腎臟中會(huì)影響腎的排泄功能,使尿酸偏高而產(chǎn)生痛風(fēng);酸性物質(zhì)沉積在關(guān)節(jié)或組織器宮內(nèi)引起相應(yīng)炎癥,導(dǎo)致關(guān)節(jié)炎等疾病;酸性物質(zhì)沉積在胰腺中,會(huì)影響胰島細(xì)胞的活性、影響胰島素的敏感性引發(fā)糖尿病及其并發(fā)癥等等。更為嚴(yán)重的是酸性物質(zhì)沉積在血液里、血管壁使血管壁增厚,引起動(dòng)脈硬化,引發(fā)中風(fēng)、心肌梗塞等各種心腦血管疾病。

            …………

            含鈉、鉀、鈣、鎂等金屬元素較多的乃是堿性食品。并非味道酸的就是酸味食品,應(yīng)該掌握一點(diǎn):所有酸味的水果、豆制品都為堿性食物而不是酸性食物,堿性食物被認(rèn)為是具有美容作用的食物。
            豆腐、牛奶、芹菜、土豆、竹筍、香菇、胡蘿卜、海帶、綠豆、香蕉、西瓜、草莓等及大部分的蔬菜、水果都是堿性的。
            食物的“酸堿性”會(huì)影響體態(tài)和皮膚健美。
             經(jīng)測(cè)定,弱堿性的食物有:豆腐、豌豆、大豆、綠豆、油菜、芹菜、番薯、蓮藕、洋蔥、茄子、南瓜、黃瓜、蘑菇、蘿卜、牛奶等。而呈堿性的食物有:菠菜、白菜、卷心菜、生菜、胡蘿卜、竹筍、馬鈴薯、海帶、柑橘類、西瓜、葡萄、香蕉、草莓、板粟、柿子、咖啡、葡萄酒等。  還有一些食物因吃起來(lái)酸,人們就錯(cuò)誤地把它們當(dāng)成了酸性食物,如山植、西紅柿、醋等,其實(shí)這些東西正是典型的堿性食物

            多吃堿性食物。研究發(fā)現(xiàn),多食堿性食物,可保持血液呈弱堿性,使得血液中乳酸、尿素等酸性物質(zhì)減少,并能防止其在管壁上沉積,因而有軟化血管的作用,故有人稱堿性食物為“血液和血管的清潔劑”。這里所說(shuō)的酸堿性,不是食物本身的性質(zhì),而是指食物經(jīng)過(guò)消化吸收后,留在體內(nèi)元素的性質(zhì)。常見(jiàn)的酸性元素有氮、碳、硫等;常見(jiàn)的堿性元素有鉀、鈉、鈣、鎂等。有的食物口味很酸,如番茄、橘子,卻都是地地道道的強(qiáng)堿性食物,因?yàn)樗鼈冊(cè)隗w內(nèi)代謝后的最終元素是鉀元素等。

            何謂酸性或堿性食物  所謂酸性食物或堿性食物,并不是指味道酸或咸的食物,而是指食物經(jīng)過(guò)消化吸收和代謝后產(chǎn)生的陽(yáng)離子或陰離子占優(yōu)勢(shì)的食物。也就是說(shuō),某種食物如經(jīng)代謝后產(chǎn)生的鉀、鈉、鈣、鎂等陽(yáng)離子占優(yōu)勢(shì)的則屬堿性食物;而代謝后產(chǎn)生磷、氯、硫等陰離子占優(yōu)勢(shì)的食物屬酸性食物。檸檬、柑桔、楊桃等味道雖酸,但它經(jīng)代謝后,有機(jī)酸變成了水和二氧化碳,后者經(jīng)肺呼出體外,剩下的陽(yáng)離子占優(yōu)勢(shì),仍屬堿性食物;同理,肉、魚、蛋類和米面雖無(wú)酸味,但代謝后產(chǎn)生的陰離子較多,仍屬于酸性食物。因此,不能從食物的味道來(lái)區(qū)分酸性或堿性食物

            看起來(lái)挺恐怖的。。。看來(lái)得注意下伙食了,以后要多吃水果、蔬菜。。。~~~

            posted @ 2006-11-10 16:09 愛(ài)上青菜的包子 閱讀(234) | 評(píng)論 (0)編輯 收藏

            2006年10月26日 #

            這幾天拿到公司以前項(xiàng)目中的一個(gè)用C++Builder做的程序,在我機(jī)器上調(diào)試,結(jié)果提示出錯(cuò):Operation not applicable

            使用斷點(diǎn)跟蹤之后發(fā)現(xiàn)錯(cuò)誤出在使用TQuery時(shí)執(zhí)行open方法時(shí),回追根源,得出以下反饋:

            m_pqQuery -> SQL -> Add(? " Select?*?From?Table1?Where?Id?=?:PId? " ?);
            m_pqQuery
            -> ParamByName(? " PId " ?) -> AsInteger????? = ?某個(gè)int變量;


            執(zhí)行完這句之后,按正常情況,參數(shù)PId應(yīng)該被賦予了一個(gè)整形值,但是Debug跟蹤顯示其值還是跟未賦值前是同樣表示的未知值。所以在執(zhí)行open方法時(shí)出錯(cuò)了。

            如果我不是用該方法,直接把SQL語(yǔ)句寫死:

            m_pqQuery -> SQL -> Add(? " Select?*?From?Table1?Where?Id?=?0? " ?);


            運(yùn)行正常

            或者用

            char ?sql[ 80 ];
            int ?n? = ?某整形變量?;
            sprintf(sql,
            " Select?*?From?Table1?Where?Id?=?%d " ,n);
            pqQuery
            -> SQL -> Add(sql);


            也運(yùn)行正常

            查了下,原來(lái)給參數(shù)賦值的方法并沒(méi)有錯(cuò)誤,編譯也能通過(guò),況且以前該程序肯定是能正常運(yùn)行的。。真是奇怪為什么在我這里就賦不上值。。調(diào)試了很久也沒(méi)能找到原因,只好作罷,為了順利運(yùn)行,只能改為sprintf和直接連接字符串的方式。
            在這里記上一筆,希望以后能夠找到原因。。。

            posted @ 2006-10-26 21:25 愛(ài)上青菜的包子 閱讀(369) | 評(píng)論 (0)編輯 收藏

            2006年9月28日 #

            1. 重載<<操作符
              要重新定義<<操作符,以便將它和cout一起用來(lái)顯示對(duì)象的內(nèi)容,請(qǐng)定義下面的友元操作符函數(shù):
              ostream?&?operator?<<?(ostream?&?os,const?c_name?&?obj)
              {
              os?
              <<?;//?display?object?contents
              return?os;
              }

              其中c_name是類名。如果該類提供了能夠返回所需內(nèi)容的公有方法,則可在操作符函數(shù)中使用這些方法,這樣便不會(huì)將他們?cè)O(shè)置為友元函數(shù)了。
            2. 轉(zhuǎn)換函數(shù)
              要將單個(gè)值轉(zhuǎn)換為類類型,需要?jiǎng)?chuàng)建原型如下所示的類構(gòu)造函數(shù):
              c_name(type_name?value);

              其中c_name為類名,type_name是要轉(zhuǎn)換的類型的名稱。
              要將類轉(zhuǎn)換為其他類型,需要?jiǎng)?chuàng)建原型如下所示的類成員函數(shù):
              operator?type_name();

              雖然該函數(shù)沒(méi)有聲明返回類型,但應(yīng)返回所需類型的值。
              使用轉(zhuǎn)換函數(shù)時(shí)要小心。可以在聲明構(gòu)造函數(shù)時(shí)使用關(guān)鍵字explicit,以防止它被用于隱式轉(zhuǎn)換。
            3. 其構(gòu)造函數(shù)使用new的類
              如果類使用new操作符來(lái)分配類成員指向的內(nèi)存,在設(shè)計(jì)時(shí)應(yīng)采取一些預(yù)防措施。
            • 對(duì)于指向的內(nèi)存是由new分配的所有類成員,都應(yīng)在類的析構(gòu)函數(shù)中對(duì)其使用delete,該操作符將釋放分配的內(nèi)存。
            • 如果析構(gòu)函數(shù)通過(guò)對(duì)指針類成員使用delete來(lái)釋放內(nèi)存,則每個(gè)構(gòu)造函數(shù)都應(yīng)當(dāng)使用new來(lái)初始化指針,或?qū)⑺O(shè)置為空指針。
            • 構(gòu)造函數(shù)中要么使用new[],要么使用new,而不能混用。如果構(gòu)造函數(shù)使用的是new[],則析構(gòu)函數(shù)應(yīng)使用delete[];如果構(gòu)造函數(shù)使用的是new,則析構(gòu)函數(shù)應(yīng)適用delete。
            • 應(yīng)定義一個(gè)分配內(nèi)存(而不是將指針指向已有內(nèi)存)的復(fù)制構(gòu)造函數(shù)。這樣程序能夠?qū)㈩悓?duì)象初始化為另一個(gè)對(duì)象。這種構(gòu)造函數(shù)原型如下:
              className(const?className?&)
            • 應(yīng)定義一個(gè)重載賦值操作符的類成員函數(shù),其函數(shù)定義如下(其中c_pointer是c_name的類成員,類型為指向type_name的指針)。下面的范例假設(shè)使用new[]來(lái)初始化變量c_pointer):
              c_name?&?c_name::operator?=?(const?c_name?&?cn)
              {
              if?(this?==?&?cn)
              return?*this;

              delete?[]?c_pointer;
              //?set?size?number?of?type_name?units?to?be?copyied
              c_pointer?=?new?type_name[size];
              //?then?copy?data?pointed?to?by?cn.c_pointer?to
              //?location?pointed?to?by?c_pointer

              return?*this;
              }

            本文對(duì)我前面幾篇隨筆中提到的問(wèn)題也作出了一個(gè)總結(jié),感覺(jué)很有必要記下來(lái)。
            以上內(nèi)容原文引用自參考書籍中內(nèi)容。

            參考書籍:C++PrimerPlus author:Stephen Prata

            posted @ 2006-09-28 15:18 愛(ài)上青菜的包子 閱讀(795) | 評(píng)論 (1)編輯 收藏

            ?

            const ? int ?BUF? = ? 512 ?;

            class ?JustTesting
            {
            ????
            private :
            ????????JustTesting(
            const ? string ? & ?s? = ? " Just?Testing " , int ?n? = ? 0 )
            ????????
            {} ?
            ????????
            ~ JustTesting() {}
            ????
            public :
            ????
            }
            ;

            int ?main()
            {
            ????
            char ? * ?buffer? = ? new ? char ?[BUF];

            ????JustTesting?
            * pc1, * pc2, * pc3, * pc4;

            ????pc1?
            = ? new ?(buffer)?JustTesting;
            ????pc2?
            = ? new ?JustTesting(? " ?Heap1? " ?,? 20 ?);

            ????pc3?
            = ? new ?(buffer? + ? sizeof ?(JustTesting))?JustTesting( " Bad?Idea " , 6 );?? // ?此處用一個(gè)JustTesging對(duì)象大小的偏移量避免pc3與pc1占用同一塊內(nèi)存,因?yàn)槿绻悇?dòng)態(tài)的為其成員分配內(nèi)存,占用同一內(nèi)存將會(huì)產(chǎn)生問(wèn)題。?
            ????pc4? = ? new ?JustTesting( " Heap2 " , 10 )?

            ????

            ????delete?pc2;
            ????delete?pc4;
            ????delete?[]?buffer;
            ????
            return ? 0 ;
            }


            以上代碼片斷中,pc1和pc3為布局new操作符來(lái)分配內(nèi)存,而pc2和pc4為常規(guī)new操作符來(lái)分配內(nèi)存?。
            對(duì)于常規(guī)new操作符分配的內(nèi)存,可以直接使用:delete?pc2; 這樣的語(yǔ)句操作來(lái)釋放內(nèi)存。

            而對(duì)于布局new操作符分配的內(nèi)存就不能這樣做:delete?pc1;

            因?yàn)閜c1和pc3并沒(méi)有直接收到new操作符返回的地址,而是由布局操作符指向了buffer的地址,new/delete系統(tǒng)知道已分配的512字節(jié)塊buffer,但對(duì)布局new操作符對(duì)該內(nèi)存塊做了何種處理一無(wú)所知。
            另一方面,buffer的地址是用new []初始化的,因此必須使用delete[]而不是delete
            注意:即使buffer是使用new而不是new[]初始化的,delete pc1 也將釋放buffer,而不是pc1。

            以上的代碼確實(shí)釋放了buffer:delete [] buffer;
            但是由此產(chǎn)生了新的問(wèn)題,它沒(méi)有為布局new操作符在該內(nèi)存塊中創(chuàng)建的對(duì)象調(diào)用析構(gòu)函數(shù),我們只需要在析構(gòu)函數(shù)中放入一段顯示語(yǔ)句就可以清楚的看到,程序并沒(méi)有銷毀“JustTesting”和“Bad Idea”,也就是pc1和pc3指向的對(duì)象。
            那么這里就需要我們顯式的為布局new操作符創(chuàng)建的對(duì)象調(diào)用析構(gòu)函數(shù)。正常情況下將自動(dòng)調(diào)用析構(gòu)函數(shù),這是需要顯示調(diào)用析構(gòu)函數(shù)的少數(shù)幾種情況之一。
            顯式調(diào)用析構(gòu)函數(shù)時(shí),必須指定要銷毀的對(duì)象。由于有指向?qū)ο蟮闹羔槪虼丝梢赃@樣寫:

            pc3->~JustTesting();
            pc1->~JustTesting();

            把這段代碼放到delete [] buffer;之前,這段程序才算完整無(wú)錯(cuò)。

            參考書籍:C++PrimerPlus author:Stephen Prata

            posted @ 2006-09-28 14:42 愛(ài)上青菜的包子 閱讀(2321) | 評(píng)論 (3)編輯 收藏

            在使用new來(lái)初始化對(duì)象的指針成員時(shí)必須特別小心,以下是幾點(diǎn)注意事項(xiàng):

            • 如果在構(gòu)造函數(shù)中使用new來(lái)初始化指針成員,則應(yīng)在析構(gòu)函數(shù)中使用delete。
            • new和delete必須相互兼容。new對(duì)應(yīng)于delete,new[]對(duì)應(yīng)于delete[]。
            • 如果有多個(gè)構(gòu)造函數(shù),則必須以相同的方式使用new,要么都帶中括號(hào),要么都不帶。因?yàn)橹挥幸粋€(gè)析構(gòu)函數(shù),因此所有的構(gòu)造函數(shù)都必須與它兼容。不過(guò)可以在一個(gè)構(gòu)造函數(shù)中使用new來(lái)初始化指針,而在另外一個(gè)構(gòu)造函數(shù)中將指針初始化為空(Null或0),這是因?yàn)閐elete(無(wú)論是帶中括號(hào)還是不帶中括號(hào))可以用于空指針。
            posted @ 2006-09-28 14:41 愛(ài)上青菜的包子 閱讀(1894) | 評(píng)論 (1)編輯 收藏

            例如有以下class:

            class ?StringBad
            {
            ????
            private :
            ????????
            char ? * ?str;
            ????????
            int ?len;
            ?????????
            ????
            public :
            ????????StringBad(
            const ? char ? * ?s);
            ????????StringBad();
            ????????
            ~ StringBad();
            ????????
            }
            ;

            在構(gòu)造函數(shù)和析構(gòu)函數(shù)定義當(dāng)中有如下定義:

            StringBad::StringBad( const ? char ? * ?s)
            {
            ????len?
            = ?std::strlen(s);
            ????str?
            = ? new ? char ?[len? + ? 1 ];
            ????
            }
            ?

            StringBad::StringBad()
            {
            ????len?
            = ? 4 ?;
            ????str?
            = ? new ? char [ 4 ];
            ????
            }
            ?

            StringBad::
            ~ StringBad()
            {
            ????
            ????delete?[]?str;
            }

            那么在程序當(dāng)中如果有以下代碼:

            StringBad?sports( " Spinach?Leaves?Bow1?for?bollars " );
            StringBad?sailor?
            = ?sports;

            以上的第二條初始化語(yǔ)句將會(huì)調(diào)用什么構(gòu)造函數(shù)?記住,這種形式的初始化等效于下面的語(yǔ)句:

            StringBad?sailor? = ?StringBad(sports);

            因?yàn)閟ports的類型為StringBad,因此相應(yīng)的構(gòu)造函數(shù)原型應(yīng)該如下:

            StringBad( const ?StringBad? & );

            當(dāng)我們使用一個(gè)對(duì)象來(lái)初始化另一個(gè)對(duì)象時(shí),編譯器將自動(dòng)生成上述構(gòu)造函數(shù)(稱為復(fù)制構(gòu)造函數(shù),因?yàn)樗鼊?chuàng)建對(duì)象的一個(gè)副本)。
            現(xiàn)在我們不妨總結(jié)一下所謂的隱式成員函數(shù),即C++自動(dòng)提供了以下這些成員函數(shù):

            • 默認(rèn)構(gòu)造函數(shù),如果沒(méi)有定義構(gòu)造函數(shù)。
            • 復(fù)制構(gòu)造函數(shù),如果沒(méi)有定義。
            • 賦值操作符,如果沒(méi)有定義。
            • 默認(rèn)析構(gòu)函數(shù),如果沒(méi)有定義。
            • 地址操作符,如果沒(méi)有定義。

            現(xiàn)在我們來(lái)看看我們沒(méi)有定義復(fù)制構(gòu)造函數(shù)的情況下調(diào)用隱式復(fù)制構(gòu)造函數(shù)將會(huì)出現(xiàn)什么情況。
            從構(gòu)造函數(shù)定義的代碼片斷可以看到,當(dāng)中使用new操作符初始化了一個(gè)指針str,而隱式的復(fù)制構(gòu)造函數(shù)是按值進(jìn)行復(fù)制的,那么對(duì)于指針str,將會(huì)進(jìn)行如下復(fù)制:

            sailor.str? = ?sports.str;

            這里復(fù)制的不是字符串,而是一個(gè)指向字符串的指針!也就是說(shuō),我們將得到兩個(gè)指向同一個(gè)字符串的指針!由此會(huì)產(chǎn)生的問(wèn)題將不言而喻。當(dāng)其中一個(gè)對(duì)象調(diào)用了析構(gòu)函數(shù)之后,其str指向的內(nèi)存將被釋放,這個(gè)時(shí)候我們?nèi)绻{(diào)用另一個(gè)對(duì)象,其str指向的地址數(shù)據(jù)會(huì)是什么?很明顯將會(huì)出現(xiàn)不可預(yù)料的結(jié)果。

            所以由此可見(jiàn),如果類中包含了使用new初始化的指針成員,應(yīng)當(dāng)定義一個(gè)復(fù)制構(gòu)造函數(shù),以復(fù)制指向的數(shù)據(jù),而不是指針,這被稱為深度復(fù)制。因?yàn)槟J(rèn)的淺復(fù)制(或成為成員復(fù)制)僅淺淺的賦值指針信息。

            我們?cè)倏匆韵麓a片斷,我們稍做修改:

            StringBad?headline1( " Celery?Stalks?at?Midnight " );
            StringBad?knot;
            knot?
            = ?headline1;

            這里的最后一行將與以上例子有所區(qū)別,現(xiàn)在是將已有對(duì)象賦給另一個(gè)已有對(duì)象,這將會(huì)采取其他操作,即使用重載的賦值操作符。(我們需要知道的是:初始化總是會(huì)調(diào)用復(fù)制構(gòu)造函數(shù),而使用=操作符時(shí)也可能調(diào)用賦值操作符)因?yàn)镃++允許對(duì)象賦值,這是通過(guò)自動(dòng)為類重載賦值操作符實(shí)現(xiàn)的。其原型如下:

            Class_name? & ?Class_name:: operator ? = ?( const ?Class_name? & );

            它接受并返回一個(gè)指向類對(duì)象的引用。
            與隱式的復(fù)制構(gòu)造函數(shù)一樣,隱式的對(duì)象賦值操作符也會(huì)產(chǎn)生同樣的問(wèn)題,即包含了使用new初始化的指針成員時(shí),只會(huì)采用淺復(fù)制。所以我們需要使用同樣的解決辦法,即定義一個(gè)重載的賦值操作符來(lái)實(shí)現(xiàn)深度復(fù)制。

            所以綜上所述,如果類中包含了使用new初始化的指針成員,我們應(yīng)該顯式定義一個(gè)復(fù)制構(gòu)造函數(shù)和一個(gè)重載的賦值操作符來(lái)實(shí)現(xiàn)其深度復(fù)制,避免由此帶來(lái)的成員復(fù)制問(wèn)題

            參考書籍:C++PrimerPlus author:Stephen Prata

            posted @ 2006-09-28 14:33 愛(ài)上青菜的包子 閱讀(1578) | 評(píng)論 (0)編輯 收藏

            很喜歡C++,學(xué)習(xí)也有一段時(shí)間了。但是看書+練手的同時(shí),總感覺(jué)有必要將自己學(xué)習(xí)中覺(jué)得重要的地方整理出來(lái),以便以后回頭參考。最終選擇了cppblog,呵呵。以后就在這里安家了~~
            筆記中參考了一些書籍中的范例和一些說(shuō)明。都是自己學(xué)習(xí)過(guò)程中整理出來(lái)的,主要目的是給自己日后參考。
            posted @ 2006-09-28 14:23 愛(ài)上青菜的包子 閱讀(436) | 評(píng)論 (1)編輯 收藏

            僅列出標(biāo)題  
            久久婷婷色综合一区二区| 久久婷婷是五月综合色狠狠| 国内精品伊人久久久久妇| 国内精品久久久久国产盗摄| 久久最近最新中文字幕大全| 国内精品人妻无码久久久影院 | 久久久久国产亚洲AV麻豆| 国产精品久久久久久影院| AAA级久久久精品无码片| 丁香五月网久久综合| 久久99国产综合精品女同| 久久av无码专区亚洲av桃花岛| 精品久久久无码21p发布| 亚洲va久久久噜噜噜久久| 亚洲精品美女久久久久99| 久久久久亚洲AV无码麻豆| 国产精品一区二区久久不卡| av国内精品久久久久影院| 99久久国产免费福利| 日本精品久久久久久久久免费| 伊人色综合久久天天网| 97久久国产露脸精品国产| 欧美午夜精品久久久久免费视| 99麻豆久久久国产精品免费| 国产精品99久久久久久猫咪 | 久久人人青草97香蕉| 亚洲国产精品无码久久久蜜芽| 久久棈精品久久久久久噜噜| 美女写真久久影院| 午夜精品久久久久| 成人久久精品一区二区三区| 国产女人aaa级久久久级| 亚洲精品午夜国产va久久| 色综合久久久久综合体桃花网| 久久免费视频观看| 国产精品久久新婚兰兰| 91视频国产91久久久| 伊人热热久久原色播放www| 午夜欧美精品久久久久久久| Xx性欧美肥妇精品久久久久久| 亚洲精品第一综合99久久|