CompBook 板


Re: 網際網路四大服務 答客問 (1) - reference and delete 侯捷 [email protected] 2000.03.26 第一次發表於 清大.楓橋驛站(140.114.87.5).電腦書訊版(Computer/CompBook) 本文將於日後整理於 侯捷網站 侯捷網站:www.jjhou.com ---------------------------------------------------------------- 網際網路四大服務 答客問 (1) 之中,我代作者王家俊先生回覆了 sammy 讀者的一個問題。但我自己亦從中心生疑惑。所以我把 答客問 (1) 轉給家俊。雖然家俊正在服兵役,卻很快做了回覆。 以下是其來信。 jcwang wrote (2000/03/26) : > 侯大哥,您好: > > 感謝您替我對讀者 sammy 做了這麼詳盡的回答。我想讀者會選擇直接 > 問侯捷而不問作者,想必是因為「侯捷」這個招牌已經成了「有問 > 必答」的代名詞,寫信問原作者還未必能得到如此詳盡的回覆呢! :) > 這是一件可喜可賀的事! > > 我把一個比較接近我原意的程式寫在下方: > > // jcw 032600 > > #include <iostream.h> > > class A // 類似原來的 CWin32TCPEnv > { > public: > int val ; > } ; > > class B // 類似原來的 ClientStub > { > public: > B( A &initval ) : val( initval ) {} > A &val ; // 請注意,這裡是 by reference,這是關鍵! > } ; > > int main( void ) > { > A myA ; > myA.val = 5 ; > > B *pB = new B( myA ) ; // B 將 myA 關聯到它的 val 成員 > > A &finalA = pB->val ; // 類似 CWin32TCPEnv &Env = pStub->m_Env ; > > cout << finalA.val << endl ; // 輸出 5 > > delete pB ; > > cout << finalA.val << endl ; // 仍舊輸出 5。顯然 delete pB > // 並未自動解構參照成員 > > return 0 ; > // 這個時候 A 才被解構。替 A 寫一個 destructor 便可知。 > } > > 所以觀察到的是 desructor 並不會呼叫其「參照成員」的 destructor > (但確定會解構其實體成員)。從我手中的資料無法判斷這是 VC++ 的 bug > 還是標準行為,不過 HelloTCPIP 能正常工作完全依據的就是這一點。 > > 請侯大哥指教。 侯捷補充: > 我想讀者會選擇直接問侯捷而不問作者,想必是因為「侯捷」這個招牌 > 已經成了「有問必答」的代名詞。 不不不。侯捷絕非「有問必答」。除了對侯捷所著所譯之書籍提出 疑惑或指正,我會比較積極回答之外,其他則要看時間、看心情、 看主題、看能力。這陣子我整理信件加以回覆,竟然有「上個世紀」 寫來的讀者來函,說實在有點不好意思。對方可能早就犯嘀咕了吧。 回到正題。上封信中,我沒有仔細看書中 ClientStub's data member Env 的宣告方式,想當然爾地以 by value 方式來宣告它: class CClientStub { ... CWin32TCPEnv m_Env; }; 書中其實是以 by reference 方式來宣告它:(p45, #0076) class CClientStub { ... CWin32TCPEnv &m_Env; // <-- a reference member }; 換句話說 CClientStub 有一個 reference member。這便是關鍵所在。 我把書中程式重新簡化如下: #include <iostream> using namespace std; class CWin32TCPEnv { public: // default ctor CWin32TCPEnv() : m_i1(9), m_i2(28) { cout << "CWin32TCPEnv default ctor \n"; } // copy ctor CWin32TCPEnv(const CWin32TCPEnv& Env) : m_i1(Env.m_i1), m_i2(Env.m_i2) { cout << "CWin32TCPEnv copy ctor \n"; } // dtor ~CWin32TCPEnv() { cout << "CWin32TCPEnv dtor \n"; } void show() { cout << m_i1 << ' ' << m_i2 << endl; } private: int m_i1, m_i2; }; class CClientStub { public: // ctor CClientStub(CWin32TCPEnv& Env) : m_Env(Env) // (c) { cout << "CClientStub ctor \n"; } // dtor ~CClientStub() { cout << "CClientStub dtor \n"; } // public data member CWin32TCPEnv &m_Env; // 注意,是個 reference member. }; void BasicServiceThread(void* lpArg) { CClientStub *pStub = (CClientStub *)lpArg; CWin32TCPEnv &Env = pStub->m_Env; delete pStub; // CClientStub dtor (a) // 這裡測試 Env 還在否? Env.show(); // 9 28。資料仍在,顯示 delete operator 並不會解構 // 「物件內之 reference member」所代表的物件。 // scope 結束前,並未喚起 Env 的 CWin32TCPEnv dtor // 因為此處 Env 是個 reference。 (b) } int main() { CWin32TCPEnv Env; // CWin32TCPEnv default ctor Env.show(); // 9 28 CClientStub *pStub = new CClientStub(Env); // CClientStub ctor BasicServiceThread(pStub); // 這裡測試 Env 還在否? Env.show(); // 9 28 // scope 結束前,喚起 Env 的 CWin32TCPEnv dtor } 讓我們從 C++ 語言層面探討之。reference members 和 pointer members 的表現有以下兩個相同點: (1) 當物件被解構,其 reference members 或 pointer members 所代表 (所指向)的物件並不會被一併解構。見上例 (a) (2) pointer 或 reference 不會因為退出 scope 而使其 「所代表之物件」被自動解構。見上例 (b)。 (但可能因為其他原因而被解構) 此外,reference member 一定得於 member initialization list 中 初始化。見上例 (c)。參考《C++ Primer 中文版》p720. 針對上述 (1),Effective C++ 的 item6 給了一個忠告: item 6 : "Use delete on pointer members in destructors." 否則會出現 memory leak 問題。 家俊說: > 我手中的資料無法判斷這是 VC++ 的 bug 還是標準行為, > 不過 HelloTCPIP 能正常工作完全依據的就是這一點。 這是 C++ 標準行為。不過一般而言,reference 主要用於 函式的型式參數(formal parameters);一般程式較少使用 reference 獨立物件。 -- the end  -- ※ Origin: 楓橋驛站<bbs.cs.nthu.edu.tw> ◆ Mail: [email protected]







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草
伺服器連線錯誤,造成您的不便還請多多包涵!
「贊助商連結」






like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Soft_Job站內搜尋

TOP