• <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>
            隨筆 - 181  文章 - 15  trackbacks - 0
            <2009年2月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            1234567

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            My Tech blog

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

                    這一部分會(huì)將要討論一下auto_ptr.c++標(biāo)準(zhǔn)庫(kù)提供auto_ptr作為一種智能指針,有了這種智能指針,就可以在異常被拋出的時(shí)候避免資源的泄漏.注意,auto_ptr只是智能指針的一種.因?yàn)槭聦?shí)上有多種智能指針存在.而auto_ptr只是被用來(lái)滿足某種情形下的需求的.而對(duì)于其他一些情形,auto_ptr無(wú)能為力.所以在使用的時(shí)候 要格外注意.
                    auto_ptr的動(dòng)機(jī)
                    通常,一個(gè)函數(shù)會(huì)按照下面的流程進(jìn)行操作:
                    1.獲取資源.
                    2.進(jìn)行一些操作.
                    3.釋放之前所獲取的資源.
                    如果函數(shù)所獲取的那些資源與本地對(duì)象綁定,它們就會(huì)在函數(shù)結(jié)束的時(shí)候被自動(dòng)釋放掉.因?yàn)楸镜貙?duì)象的析構(gòu)函數(shù)會(huì)被調(diào)用.但是如果資源被顯式獲取,并且沒(méi)有與任何對(duì)象綁定,它們必須也被顯式的釋放掉.在使用指針的時(shí)候,資源通常是被顯式管理的.
                    一種典型的像上面這樣使用資源的方式就是使用new來(lái)創(chuàng)建和用delete來(lái)釋放.
                    但是作釋放用的delete操作往往被忽略(特別是函數(shù)有返回值的時(shí)候).當(dāng)然,出現(xiàn)異常的時(shí)候,也同樣會(huì)發(fā)生這種風(fēng)險(xiǎn).因?yàn)楫惓S锌赡荞R上停止你函數(shù)的執(zhí)行,而不去進(jìn)行delete釋放.結(jié)果就是內(nèi)存泄漏,或者說(shuō)得寬泛一些,是"資源泄漏".為了避免資源泄漏,通常需要函數(shù)能夠捕獲所有的異常.隨之而來(lái)的就是,代碼變得越來(lái)越復(fù)雜,冗長(zhǎng).
                    伴隨著這種情況的發(fā)生,一種智能指針auto_ptr出現(xiàn)了.在任何時(shí)候,一旦指針本身被銷毀,它所指向的數(shù)據(jù)也會(huì)被銷毀.此外,因?yàn)橹悄苤羔樖且粋€(gè)本地變量,不管函數(shù)到底是因?yàn)檎=Y(jié)束,還是因?yàn)榉钦=Y(jié)束,auto_ptr所指向的數(shù)據(jù)都會(huì)被銷毀.
                    有了auto_ptr,delete語(yǔ)句和catch語(yǔ)句就變得不那么必要了.auto_ptr和普通指針的使用方式基本相同,即用樣用"*"表示它所指向的對(duì)象,同樣用"->"來(lái)訪問(wèn)所指向?qū)ο蟮某蓡T方法.但是有關(guān)指針的運(yùn)算(比如指針的自加)不被支持(這也許是一個(gè)優(yōu)點(diǎn),因?yàn)橹羔樳\(yùn)算也許會(huì)造成一些麻煩).
                    注意auto_ptr<>不允許你使用指派的方式來(lái)聲明它所指向的對(duì)象,比如:
                    下面的操作是不允許的:
                    std::auto_ptr<ClassA> ptr2 = new ClassA; //ERROR
                    而應(yīng)該采用顯式的構(gòu)造函數(shù)來(lái)初始化:
                    std::auto_ptr<ClassA> ptr1(new ClassA);  //OK
                    通過(guò)auto_ptr來(lái)轉(zhuǎn)換所有權(quán)
                    auto_ptr在語(yǔ)意上提供了對(duì)于所有全的嚴(yán)格約束.這意味著因?yàn)槿绻粋€(gè)auto_ptr刪除了它所指向的對(duì)象,那么這個(gè)對(duì)象將不會(huì)被其他任何對(duì)象所擁有.兩個(gè)或以上的auto_ptr絕不能同時(shí)擁有一個(gè)對(duì)象.不幸的是,這種情況是有可能出現(xiàn)的.所以只能有程序員來(lái)確保這種情況不會(huì)發(fā)生.
                    那么在這種情況下,auto_ptr的拷貝構(gòu)造函數(shù)如何工作呢?通常它會(huì)把一個(gè)對(duì)象的數(shù)據(jù)復(fù)制給另外一個(gè)對(duì)象,但是在這里,恰恰是這種行為會(huì)導(dǎo)致兩個(gè)auto_ptr擁有相同對(duì)象這種情況的出現(xiàn).解決方法很簡(jiǎn)單,但是卻得出了一個(gè)重要結(jié)論:auto_ptr的拷貝構(gòu)造函數(shù)和指派操作促成了auto_ptr對(duì)于對(duì)象所有權(quán)的一次移交.
                    看一下下面的代碼:
                    //initialize an auto_ptr with a new object
                    std::auto_ptr<ClassA> ptr1(new ClassA);
                    //copy the auto_ptr
                    //- transfers ownership from ptr1 to ptr2
                    std::auto_ptr<ClassA> ptr2(ptr1);
                    第一句中,ptr1擁有new所創(chuàng)建的那個(gè)對(duì)象.然后第二句把對(duì)于對(duì)象的所有權(quán)從ptr1轉(zhuǎn)移給了ptr2.所以在第二句之后,ptr2擁有new創(chuàng)建的那個(gè)對(duì)象的所有權(quán),而ptr1則自動(dòng)失去了對(duì)于那個(gè)對(duì)象的所有權(quán).ClassA只會(huì)在ptr2被析構(gòu)的時(shí)候被釋放掉.
                    同樣,對(duì)于一次指派操作也是如此.如下所示:
                    //initialize an auto_ptr with a new object
                    std::auto_ptr<ClassA> ptr1(new ClassA);
                    std::auto_ptr<ClassA> ptr2; //create another auto_ptr
                    ptr2 = ptr1;        //assign the auto_ptr
                                              //- transfers ownership from ptr1 to ptr2
                    注意,隨著所有權(quán)的移交,之前失去對(duì)象所有權(quán)的那個(gè)auto_ptr就變成了一個(gè)空指針.
                    當(dāng)然,還可以讓這個(gè)失去所指的空指針重新指向一個(gè)對(duì)象,像下面這樣:
                    std::auto_ptr<ClassA> ptr;               //create an auto_ptr
                    ptr = std::auto_ptr<ClassA>(new ClassA); //OK, delete old object and own new
                    對(duì)于所指向的對(duì)象的所有權(quán)的變換為我們提供了auto_ptr的一種潛在用法.函數(shù)可以使用向其他的函數(shù)傳遞所有權(quán).這包含兩種情況.
                    1.傳入函數(shù)的對(duì)象不再使用.即在auto_ptr作為參數(shù)傳遞的時(shí)候.在這種情況下,被調(diào)用的函數(shù)得到了傳入的auto_ptr所指向的那個(gè)對(duì)象的所有權(quán).因此,如果函數(shù)不再將對(duì)象的所有權(quán)轉(zhuǎn)移出來(lái),那么對(duì)象就會(huì)在函數(shù)的調(diào)用結(jié)束之后銷毀.
                     2.函數(shù)要向外傳出對(duì)象.當(dāng)auto_ptr被返回的時(shí)候,所有權(quán)由被調(diào)用的函數(shù)轉(zhuǎn)移給調(diào)用方.
                     由于auto_ptr總是牽扯到對(duì)象所有權(quán)變換的問(wèn)題,所以在使用的時(shí)候一定要注意你是否真的要轉(zhuǎn)換這個(gè)所有權(quán).
                     你可能打算通過(guò)引用傳遞auto_ptr(s).但是這樣做有可能最終你都不清楚所有權(quán)的歸屬了.總之,這不是一個(gè)好的決定或設(shè)計(jì).
                    從auto_ptr的概念出發(fā),你可能會(huì)覺(jué)得即使是傳遞常指針的話,對(duì)象的歸屬也會(huì)改變.如果這種情況可能發(fā)生,那將是非常危險(xiǎn)的.因?yàn)槿藗兛偸遣黄诖粋€(gè)成為"常量"的東西發(fā)生改變.幸運(yùn)的是,通過(guò)一些技術(shù)上的處理,這樣做是不可能的.如:
                   
             1 #include<iostream>
             2 using namespace std;
             3 int getValue(auto_ptr<int>);
             4 int main()
             5 {
             6     const auto_ptr<int> myAutoPtr=auto_ptr<int>(new int);
             7     *myAutoPtr=10;
             8     cout<<getValue(myAutoPtr)<<endl;
             9     
            10 }
            11 int getValue(auto_ptr<int> ptr)
            12 {
            13     return 10*(*ptr);
            14 }
                   上面首先定義了常量的auto_ptr,這就表明,這個(gè)auto_ptr不能將自己所指對(duì)象的所有權(quán)傳遞給其他對(duì)象.因而調(diào)用函數(shù)getValue的時(shí)候如果傳遞了上面定義的auto_ptr,就會(huì)被編譯器發(fā)現(xiàn),并作為編譯錯(cuò)誤反饋回來(lái):
            錯(cuò)誤: passing ‘const std::auto_ptr<int>’ as ‘this’ argument of ‘std::auto_ptr<_Tp>::operator std::auto_ptr_ref<_Tp1>() [with _Tp1 = int, _Tp = int]’ discards qualifiers
            將auto_ptr(s)作為成員變量
            當(dāng)然,如果在類中使用auto_ptr的時(shí)候,你同樣也可以避免資源泄漏這種問(wèn)題的發(fā)生.如果你使用auto_ptr取代通常的指針的話,你將不再需要對(duì)那些對(duì)象進(jìn)行手動(dòng)的析構(gòu)處理.同時(shí),auto_ptr也能夠有效避免因?yàn)槌跏蓟惓6鴮?dǎo)致資源泄漏這種情況的發(fā)生.因?yàn)槲鰳?gòu)總是在構(gòu)造之后,所以如果在構(gòu)造的時(shí)候發(fā)生異常,你往往不能夠及時(shí)釋放資源,進(jìn)而導(dǎo)致資源泄漏情況的發(fā)生.
                    但是,在享用了auto_ptr帶來(lái)的諸多好處的同時(shí),你在處理拷貝構(gòu)造函數(shù)和重載賦值操作的時(shí)候,要格外注意auto_ptr所有權(quán)變換的問(wèn)題.當(dāng)然,避免這類問(wèn)題的最好方法就是使用常量指針.
                    有關(guān)auto_ptr(s)的濫用
                    auto_ptr能夠滿足一些需要,特別是容易發(fā)生資源泄漏的時(shí)候,它總能夠發(fā)揮好的效果.但是在使用它的時(shí)候仍然需要注意,不要濫用.在使用的時(shí)候,要注意以下幾點(diǎn):
                    1.auto_ptr(s)不能夠共享對(duì)于所指向?qū)ο蟮乃袡?quán).
                    2auto_ptr(s)不提供對(duì)于數(shù)組的支持.因?yàn)樵卺尫刨Y源的時(shí)候,auto_ptr使用的是delete而不是delete[].當(dāng)然,對(duì)于數(shù)組而言,STL也有相應(yīng)的處理辦法,比如容器.
                    3.auto_ptr(s)不是智能指針的全部.注意它并不能解決一切問(wèn)題.注意它的應(yīng)用場(chǎng)景.
                    4.auto_ptr(s)不能滿足容器中對(duì)象的操作要求.

                   







                   

            posted on 2007-07-12 22:46 littlegai 閱讀(345) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 我的讀書筆記
            91精品国产91久久久久久| 亚洲?V乱码久久精品蜜桃| 伊人久久成人成综合网222| 欧美久久一区二区三区| 国产精品亚洲综合久久| 久久91精品国产91久| 欧美va久久久噜噜噜久久| 久久精品夜夜夜夜夜久久| 狠狠狠色丁香婷婷综合久久五月| 精品水蜜桃久久久久久久| 一本一本久久a久久精品综合麻豆| 色综合久久久久无码专区| 青青青青久久精品国产h| 久久亚洲中文字幕精品一区| 久久国产欧美日韩精品| 久久精品国产黑森林| 无码日韩人妻精品久久蜜桃| 久久99免费视频| 色妞色综合久久夜夜| 久久国产亚洲精品麻豆| 国产欧美久久久精品影院| 国内精品久久久久影院日本| 精品欧美一区二区三区久久久| 久久精品人成免费| 亚洲人AV永久一区二区三区久久 | 综合久久精品色| 99热都是精品久久久久久| 99精品久久久久久久婷婷 | 亚洲AV无一区二区三区久久| 夜夜亚洲天天久久| 国产精品久久亚洲不卡动漫| 亚洲精品乱码久久久久久| 久久天天躁狠狠躁夜夜不卡 | 99久久久精品免费观看国产| 久久福利资源国产精品999| 久久精品无码av| 九九久久精品无码专区| 狠狠人妻久久久久久综合蜜桃| 久久精品国产秦先生| 91久久精品无码一区二区毛片| 2020久久精品国产免费|