c老師智能指針_第1頁
c老師智能指針_第2頁
c老師智能指針_第3頁
c老師智能指針_第4頁
c老師智能指針_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、Solmyr 的小品文系列之五:午餐時間。收集 轉(zhuǎn)自 pchomezero 坐在餐桌前,機械的重復(fù)“夾菜 - 咀嚼 - 吞咽”的動作序列,臉上用無形的大字寫著:我心不在焉。在他的對面坐著 Solmyr ,慢條斯理的吃著他那份午餐,維持著他一貫很有修養(yǎng)的形象 或者按照 zero 這些熟悉他本質(zhì)的人的說法:假象。“怎么了 zero ?胃口不好么?”,基本填飽肚子之后,Solmyr 覺得似乎應(yīng)該關(guān)心一下他的學(xué)徒了?!斑?,沒什么,只是 Solmyr ,C+ 為什么不支持收集呢?(注:垃圾收集是一種機制,保證動態(tài)分配了的內(nèi)存塊會自動語言支持這一機制。)”,Java 等Solmyr 嘆了口氣,用一種平靜的

2、眼神盯著 zero :“是不是在上和人吵C+ 和 Java 哪個更好?而且吵輸了?我早告訴過你,這種爭論再無聊不過了?!薄斑?是”,zero 不得不承認(rèn) Solmyr 的眼神雖然一點也不銳利,但是卻莫名其妙的讓 zero 產(chǎn)生了微微的恐懼感?!岸遥l告訴你 C+ 不支持收集的?”“啊!Solmyr 你不是開玩笑吧?!”“zero 你得轉(zhuǎn)變一下觀念。我問你,C+ 支不支持可以動態(tài)改變大小的數(shù)組?”“這 好象也沒有吧?”“那vector 是什么東西?”“呃”“支持一種特性,并不是說非得把這個特性加到語法里去,也可以選擇用現(xiàn)有的語言機制實現(xiàn)一個支持這個特征。以收集為例,這里的任務(wù)是要保證每一個態(tài)分

3、配的內(nèi)存塊都能夠被,也就是說 ”,Solmyr 不知從哪里找出了一張紙、一支筆,寫到:* p = new; / 1 delete p; / 2“也就是說,對于每一個 1 ,要保證有一個 2 被調(diào)用,1 和 2 必須成對出現(xiàn)。我來問你,C+ 中東西是由語言本身保證一定成對出現(xiàn)的?”“”,zero 露出了努力搜索的表情,不過很明顯一無所獲?!疤崾疽幌?,和類的創(chuàng)建有關(guān)?!薄芭?!構(gòu)造函數(shù)與析構(gòu)函數(shù)!”“正確??上胀ㄖ羔槢]有構(gòu)造函數(shù)與析構(gòu)函數(shù),所以一層包裝,最簡單的就象這樣:”須要寫一個類來加class my_ptrpublic:*m_p;my_my_;ptr(* p) m_p = p; ptr()

4、delete m_p; my_ptrpi(new= 10;);*(pi.m_p)“這里可以放心的使用 my_ptr ,不用擔(dān)心內(nèi)存泄漏的問題:一旦 pi 這個變量被銷毀,知道 pi.p 指向的內(nèi)存塊一定會被。不過如果每次使用my_ptr 都得去它的成員未免太麻煩了。為此,可以給這個類加上重載的* 運算符:”class my_ptrprivate:* m_p;public:my_my_ptr(* p) m_p = p; ptr() delete m_p; &operator*() return *m_p; ;my_ptr pi;*pi = 10;a = *pi;“現(xiàn)在是不是看起來 my_ptr

5、就像是一個真正的指針了?正因為如此,這種技術(shù)被稱為智能指針?,F(xiàn)在我問你,這個類還缺少哪些東西?”zero 皺著眉頭,眼睛一眨一眨,看上去就像一臺慢速電腦正在辛苦的往它的硬盤上拷貝文件。良久,zero 抬起頭來,不太確定的說:“是不是還缺少一個拷貝構(gòu)造函數(shù)和一個賦值運算符?”“說說為什么。”,Solmyr 顯然不打算就這樣放過 zero。“因為 我記得沒錯的話 50 誡 (注:指Effective C+ 2/e一書)中提到過,如果你的類里面有指針指向動態(tài)分配的內(nèi)存,那么一定要為它寫一個拷貝構(gòu)造函數(shù)和一個賦值運算符 因為 否則的話,一旦你做了賦值,會導(dǎo)致兩個對象的指針指向同一塊內(nèi)存。對了!如果是上

6、面的類,這樣一來會導(dǎo)致同一個指針被 delete 兩次!”“正確。那么應(yīng)該怎樣來實現(xiàn)呢?”“這簡單,用 memcpy 把目標(biāo)指針指向的內(nèi)存中的內(nèi)容拷貝過來?!薄叭绻闹悄苤羔樦赶蛞粋€類的對象怎么辦?注意,類的對象中可能有指針,不能用 memcpy?!薄澳?用拷貝構(gòu)造的辦法?!薄叭绻闹悄苤羔樦赶虻膶ο蟛荒芸截悩?gòu)造怎么辦?它可能有一個私有的拷貝構(gòu)造函數(shù)?!薄澳?”,zero 頓了一頓,決定老實承認(rèn),“我不知道?!薄皢栴}在哪你知道么?在于你沒有把智能指針看作指針。想象一下,如果對一個指針做賦值,它的含義是什么?”“呃,我明白了,在這種情況下,應(yīng)該想辦法讓兩個智能指針指向同一個對象 Solmyr ,

7、這樣以來豈不是仍然要對同一個對象刪除兩遍?”“是的,得想辦法解決這 個問題,辦法不只一種。比較好的一種是為每個計數(shù)值,每次賦值或者拷貝構(gòu)造,就讓計數(shù)值加一,這意味著指針一個指向這個內(nèi)存塊的智能指針又多了一 個;而每有一個智能指針被銷毀,就讓計數(shù)值減一,這意味著指向這個內(nèi)存塊的智能指針少了一個;一旦計數(shù)值為就內(nèi)存塊。象這樣:”0,class my_private:* m_p;ptr* m_count;public: my_ptr(m_p = p;* p)m_count = new; / 初始化計數(shù)值為 1*m_count = 1;my_ptr(const my_ptr& rhs) / 拷貝構(gòu)造函

8、數(shù)m_p = rhs.m_p; / 指向同一塊內(nèi)存m_count = rhs.m_count; / (*m_count)+; / 計數(shù)值加使用同一個計數(shù)值1my_ptr()(*m_count)-; / 計數(shù)值減1if( *m_count = 0 ) / 已經(jīng)沒有別的指針指向該內(nèi)存塊了delete m_p; delete m_count;my_ptr& operator=(const my_ptr& rhs)if( m_p = rhs.m_p ) / 首先判斷是否本來就指向同一內(nèi)存塊return *this; / 是則直接返回(*m_count)-; / 計數(shù)值減 1 ,因為該指針不再指向原來內(nèi)

9、存塊了if( *m_count = 0 ) / 已經(jīng)沒有別的指針指向原來內(nèi)存塊了delete m_p; delete m_count;m_p = rhs.m_p; / 指向同一塊內(nèi)存m_count = rhs.m_count; / 使用同一個計數(shù)值(*m_count)+; / 計數(shù)值加 1;“其他部分沒太大變化,我不費事了。現(xiàn)在想象一下怎樣使用這種智能指針?”,Solmyr 放下了筆,再次拿起了筷子,有些惋惜的發(fā)現(xiàn)他愛吃丸子已經(jīng)冷了。zero 想象著,有些遲疑?!?可以用 new表達(dá)式作為構(gòu)造函數(shù)的參數(shù)來構(gòu)造一個智能指針,然后 然后可以任意的賦值,”,他開始抓住了思路,越說越快,“任意的用已經(jīng)

10、存在的智能指針來構(gòu)造新的智能指針,智能指針的賦值運算符、拷貝構(gòu)造函數(shù)和析構(gòu) 會保證計數(shù)值始終等于指向該內(nèi)存塊的智能指針數(shù)?!眤ero 似乎明白了他看到了怎樣的功能,開始激動起來:“然后一旦計數(shù)值為 0 被分配的內(nèi)存塊就會!也就是說 有指針指向內(nèi)存塊,它就不,一旦沒有,它就自動!太棒了!只要一開始正確的初始化智能指針,就可以象普通指針那樣使用它,而且完全不用擔(dān)心內(nèi) 存的在飯桌問題!太棒了!”zero 激動的大叫:“這就是收集!Solmyr !上實現(xiàn)了一個收集器!”Solmyr 很明顯沒有zero 的激動:“我在吃飯,你能不能不要大叫飯桌上實現(xiàn)了一個收集器這種倒胃口的話?”頓了一頓,Solmyr

11、帶著他招牌式的壞笑,以一種可惡的口吻說道:“而且請注意一下自己的形象?!薄班??”,zero 回過神來,發(fā)現(xiàn)自己不知什么時候站了起來,而整個餐廳里的人都在他嘿嘿偷笑,這讓他感覺自己像個傻瓜。zero 紅著臉坐下,壓低了聲音問 Solmyr :“不過 Solmyr ,這確實是一個的收集機制啊,只要把這個類改成 嗯 改成模板類,象這樣:”zero 抓過了紙筆,寫到:template class my_ptrprivate:T* m_p;* m_count;“它不就能支持任意類型的指針了嗎?就可以把它用在任何地方?!盨olmyr 搖了搖頭:“不,你把問題想的太簡單了。對于簡單的類型,這個類確實可以處理的很好,但實際情況是很復(fù)雜的??紤]一個典型情況:類 Derived 是類 Base 的派生類,希望這樣賦值:”Base* pb; Derived pd;pb = pd;“你倒說說看,這種情況,怎樣改用上面這個智能指針來處理?”“”,zero 沉默了?!耙獙崿F(xiàn)一個完整的收集機制并不容易,因為有許多細(xì)節(jié)要考慮?!?,Solmyr開始總結(jié)了,“不過,基本思路就是上面說的這些。值得慶幸的是,目前已經(jīng)有了一個相當(dāng)成計數(shù)智能指針,b

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論