欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

讀書筆記effectivec++Item13用對象來管理資源

正文

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名注冊虛擬主機、營銷軟件、網(wǎng)站建設(shè)、鐵東網(wǎng)站維護、網(wǎng)站推廣。

回到頂部

1.不要手動釋放從函數(shù)返回的堆資源

假設(shè)你正在處理一個模擬Investment的程序庫,不同的Investmetn類型從Investment基類繼承而來,

1 class Investment { ... }; // root class of hierarchy of2 3 // investment types

進一步假設(shè)這個程序庫通過一個工廠函數(shù)(Item 7)來給我們提供特定Investment對象:

讀書筆記 effective c++ Item 13 用對象來管理資源

1 Investment* createInvestment(); // return ptr to dynamically allocated2 3 // object in the Investment hierarchy;4 5 // the caller must delete it6 7 // (parameters omitted for simplicity)

讀書筆記 effective c++ Item 13 用對象來管理資源

正如注釋所表述的,當(dāng)createInvesment返回的對象不再被使用時,調(diào)用者有責(zé)任將此對象釋放掉。我們用函數(shù)f來履行這個職責(zé):

讀書筆記 effective c++ Item 13 用對象來管理資源

 1 void f() 2  3 { 4  5 Investment *pInv = createInvestment(); // call factory function 6  7 ... // use pInv 8  9 delete pInv; // release object10 11 }

讀書筆記 effective c++ Item 13 用對象來管理資源

 

這個方法看上去挺好,但是在一些情況下釋放從createInvestment得來的對象有可能會失敗。在函數(shù)的”…”部分中有可能會出現(xiàn)過早的reture語句,如果這個return被執(zhí)行了,那么最后的delete語句永遠(yuǎn)不會被執(zhí)行到;如果createInvesment和delete在一個循環(huán)中,break和goto語句會使循環(huán)過早退出,delete也不會被執(zhí)行到;最后在…中的一些語句有可能會拋出異常,如果這樣的話,控制流程會再次不能執(zhí)行到delete。不管delete是怎么被跳過去的,不僅會泄露Invesment對象所使用的內(nèi)存,也會泄露Investment對象所擁有的任何資源。

當(dāng)然,小心的編程可以防止這類錯誤的發(fā)生,但是你應(yīng)該想到隨著時間的推移代碼有可能發(fā)生變化。在軟件的維護過程中,一些人可能在沒有完全領(lǐng)會這個函數(shù)的資源管理策略的情況下為其添加一個return或者continue語句。更糟糕的是,f函數(shù)的”…”部分有可能調(diào)用一個從來沒有拋出異常的函數(shù),但這個函數(shù)被“改善”后,它拋出異常了。所以依賴f來到達delete語句通常是不可行的。

回到頂部

2.通過對象來管理需要手動釋放的資源

為了確保從createInvestment返回的資源總是被釋放,我們需要將資源放到一個對象中,當(dāng)離開函數(shù)f的時候,對象的析構(gòu)函數(shù)會自動釋放對象擁有的資源。事實上,我們已經(jīng)說出了這個條款一半的內(nèi)容:通過將資源放入對象中,我們可以依賴c++的析構(gòu)函數(shù)自動調(diào)用機制來確保資源被釋放。(另一半一會就會講到)

2.1 使用auto_ptr來管理資源

 

許多資源是被動態(tài)的分配在堆上的,它們被用在一個單獨的塊或者函數(shù)中,當(dāng)控制流離開塊或者函數(shù)時,這些資源應(yīng)該被釋放。標(biāo)準(zhǔn)庫中的auto_ptr正是為這種情況量身定做的。Auto_ptr是一個指針(智能指針)一樣的對象,它的析構(gòu)函數(shù)會自動為其指向的對象調(diào)用delete函數(shù)。下面演示如何使用auto_ptr來防止可能出現(xiàn)的資源泄露:

讀書筆記 effective c++ Item 13 用對象來管理資源

 1 void f() 2  3 { 4  5 std::auto_ptr<Investment> pInv(createInvestment()); // call factory 6  7 // function 8  9 ... // use pInv as10 11 // before12 13 } // automatically14 15 // delete pInv via16 17 // auto_ptr’s dtor

讀書筆記 effective c++ Item 13 用對象來管理資源

 

2.2 用對象管理資源的兩個關(guān)鍵點

這個簡單的例子指出了使用對象管理資源的兩個關(guān)鍵點:

  • 獲取資源后應(yīng)該立即將其轉(zhuǎn)交給資源管理對象。從上面的例子看出,使用createInvestment返回的資源來初始化對其進行管理的auto_ptr指針。事實上,用對象來管理資源的想法通常被叫做”資源獲取的時候就是初始化的時候”(Resource Acquisition Is Initialization RAII),因為將資源獲取和資源管理對象的初始化放在同一個語句中是非常常見的。有時用獲取的資源給資源管理對象賦值而不是初始化,但是不管哪種方法,都是在資源獲取到之后馬上將控制權(quán)轉(zhuǎn)交給資源管理對象。

  • 資源管理對象使用它們的析構(gòu)函數(shù)來確保資源被釋放。因為不管控制流是怎么離開塊或函數(shù)的,對象銷毀的時候析構(gòu)函數(shù)會被自動調(diào)用(例如當(dāng)一個對象超出了作用域),資源因此能夠被正確釋放。釋放資源時拋出異常會使問題變的棘手,這個問題在Item8中討論了,我們不再擔(dān)心這種問題。

因為 當(dāng)auto_ptr被銷毀時會自動delete它所指向的資源,所以有沒有多個auto_ptr指向通一個對象是很重要的。如果有多個,對象會被多次delete,這就會導(dǎo)致出現(xiàn)未定義行為。為了防止這樣的問題出現(xiàn),auto_ptrs有一個與眾不同的性質(zhì):被拷貝的指針(通過拷貝構(gòu)造函數(shù)或者拷貝賦值運算符)會被置為null,進行拷貝的指針將擁有資源的所有權(quán)

讀書筆記 effective c++ Item 13 用對象來管理資源

 1 std::auto_ptr<Investment> // pInv1 points to the 2  3 pInv1(createInvestment()); // object returned from 4  5 // createInvestment 6  7 std::auto_ptr<Investment> pInv2(pInv1); // pInv2 now points to the 8  9 // object; pInv1 is now null10 11 pInv1 = pInv2; // now pInv1 points to the12 13 // object, and pInv2 is null

讀書筆記 effective c++ Item 13 用對象來管理資源

 

2.3 用shared_ptr來管理資源

奇特的拷貝行為,加上“不能有超過一個的auto_ptr指向被auto_ptr管理的資源”,這兩種特性使得auto_ptrs不是管理所有動態(tài)分配資源的最好方法。舉個例子,STL容器需要”正常的”拷貝行為,因此就不能將容器放入auto_ptr中。

 

Auto_ptr的一種替代方法是使用“引用計數(shù)的智能指針”(reference-counting smart pointer RCSP).RCSP是一種能夠跟蹤有多少對象指向同個一特定資源的指針,資源只有在沒有指針指向的情況下才能被釋放。因此,RCSP提供的行為同垃圾回收機制類似。和垃圾回收機制不同的是,RCSP不會制止循環(huán)引用(例如,兩個都不被使用的對象卻指向彼此,看上去在被使用一樣。)

TR1的tr1::shared_ptr(看Item54)是是一個RCSP,所以你可以這么實現(xiàn)f:

讀書筆記 effective c++ Item 13 用對象來管理資源

 1 void f() 2  3 { 4  5 ... 6  7 std::tr1::shared_ptr<Investment> 8  9 pInv(createInvestment()); // call factory function10 11 ... // use pInv as before12 13 } // automatically delete14 15 // pInv via shared_ptr’s dtor

讀書筆記 effective c++ Item 13 用對象來管理資源

 

這段代碼看上去同使用auto_ptr大致相同,但是拷貝shared_ptrs的行為更加自然:

讀書筆記 effective c++ Item 13 用對象來管理資源

 1 void f() 2  3 { 4  5 ... 6  7 std::tr1::shared_ptr<Investment> // pInv1 points to the 8  9 pInv1(createInvestment()); // object returned from10 11 // createInvestment12 13 std::tr1::shared_ptr<Investment> // both pInv1 and pInv2 now14 pInv2(pInv1); // point to the object15 pInv1 = pInv2; // ditto — nothing has16 // changed17 ...18 } // pInv1 and pInv2 are19 // destroyed, and the20 // object they point to is21 // automatically deleted

讀書筆記 effective c++ Item 13 用對象來管理資源

 

因為拷貝tr1::shared_ptrs的工作方式是你所想要的,它們可以被用在像STL容器和其他上下文中,在這里auto_ptr的古怪的拷貝方式不再合適。

2.4 不要將auto_ptr和shared_ptr用于動態(tài)分配數(shù)組

不要被誤導(dǎo)。這個條款不是用來介紹關(guān)于auto_ptr,tr1::shared_ptr或者其它類型的智能指針。這個條款講述的是用對象管理資源的重要性。使用Auto_ptr和tr1::shared_ptr只是舉個例子。(關(guān)于tr1::shared_ptr的更多內(nèi)容,查看Item14 18和54)

Auto_ptr和tr1::shared_ptr的析構(gòu)函數(shù)中使用的是delete而不是delete[]。(Item16 描述了區(qū)別)這意味著在auto_ptr或者tr1::shared_ptr中存放動態(tài)分配的數(shù)組不是一個好方法,令人遺憾的是,這種用法可以通過編譯:

1 std::auto_ptr<std::string> // bad idea! the wrong2 3 aps(new std::string[10]); // delete form will be used4 5 std::tr1::shared_ptr<int> spi(new int[1024]); // same problem

 

你會驚奇的發(fā)現(xiàn)c++中沒有用于動態(tài)分配數(shù)組的類似auto_ptr或者tr1::shared_ptr的東西,TR1中也沒有。因為vector和string基本可以替代動態(tài)分配數(shù)組了。如果你仍然認(rèn)為存在用于動態(tài)分配數(shù)組的類似于auto_ptr和tr1::shared_ptr的類是好的,可以看一下Boost(Item 55).你會非常高興的發(fā)現(xiàn)boost::scoped_array和boost::shared_array類提供了你正在尋找的。

回到頂部

3.其他問題

這個條款中,使用對象管理資源的指導(dǎo)方針意味著如果你自己手動釋放資源(例如使用delete而不是一個資源管理類),你的做法就是錯誤的。 預(yù)裝的資源管理類,像auto_ptr和tr1::shared_ptr使遵守這個條款變的更加容易,但有時候當(dāng)你使用一個資源的時候你會發(fā)現(xiàn)這些預(yù)制的類沒有做到你想要的。這種情況下,你就需要編寫你自己的資源管理類了。這也不是非常難的,但確實有一些微妙的地方需要你考慮。這些注意點將要在Item14和Item15種進行討論。

 

最后,我必須指出createInvestment的原生指針返回類型是資源泄露的×××,因為調(diào)用者很容易就會忘記調(diào)用delete(即使使用auto_ptr和tr1::shared_ptr來執(zhí)行delete,它們?nèi)匀恍枰浀脤reateInvestment的返回值放入智能指針對象中)。對付這個問題需要調(diào)用createInvestment的修訂版本,這個問題會在Item18中進行討論。

本文名稱:讀書筆記effectivec++Item13用對象來管理資源
轉(zhuǎn)載來源:http://chinadenli.net/article40/gojdeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)全網(wǎng)營銷推廣自適應(yīng)網(wǎng)站微信公眾號網(wǎng)站策劃網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)