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灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP