来看看 MFC 怎么实作 CString
MFC 在 CString 也是用一种 ref count 机制
而且 MFC 完全公开 source code,也没扩充保留字
有人还把它给拷了,送到没 MFC 但有 C++ 的地方去用
网络上好像找得到,叫 CxString (至少敝公司有维护一套)
CString F1()
{
CString str = "xxx"; // 产生一个字串, ref = 1
return str; // 使用 RC 的书怎么教的? 书上说 str 在离开堆叠时就消失了,
// 所以要 retain
}
那 CString 怎么做呢?
以下是我理解的看法
(书上不是这样教的,总之 source code 公开,去 trace 一下可以印证我的看法)
它把函式的输出结果也当一个变量
你可以想像有一个变量叫做
CString ret;
所以在 F1() 的最后一行, return str;
其实是执行了 ret = str;
然后外面 caller 端再去接这个 ret
比如 caller 端如果是写
CString str2 = F1();
那这里就等于有 str2 = ret; //这个 ret 是刚刚 F1 函式的传回值
然后 ret 就释放了 (写在 CString 的 destructor, ~CString)
如果没人去接,也就是单纯呼叫 F1()
那 ret 也会先接,然后再释放
总之 ref count 的计算是完美的
然后在 ref count 为 0 时, CString 会把内部物件真的释放掉
这一切,不必 precompiler 特别帮忙,不必扩充 C++
它是由标准 C++ 组成的 MFC 完成的,可以转移到没有 MFC 的 C++ compiler 去
若说有什么缺点.. 有
那就是只有 CString 写这么好用
如果我想自己写一个 class, 就不会自动被赋与这么漂亮的机制,要 coding 一堆东西
这其中包括要去覆写 operator, constructor, destructor 等等
然后还有很烦的,比如 operator + 这个 function, 和 const operator + 是不一样的
(就是多了个 const 而已啊..)
要各别覆写,即使内部的 code 其实是一模一样
operator = 和 constructor 可能是不一样的
差异在 ref count 的计算方式
也就是说,想打造一个自己的 class 和 CString 一样好用,要写很多 code
比较简单的方法是 template,不过我和它不熟
听说用 template 可以很快的产生自己的 auto ref count style class.....
在看到 Obj C 的 ARC 时,我以为它是完美的把这套搬进 Compiler
所以我就这么写
- (NSString*)F1
{
NSString* str = @"xxx";
return str;
}
外面 caller 端是
NSString* str2 = [self F1];
以上对 ref 的讨论会一模一样吗? 也就是函式执行结束时,等于有一个中介变量 ret
如果有这种东西,那其实是用不到 autorelease 才对
因为 compiler 帮我们加了 retain & release
return str; //这里要往外传,所以加一个 retain
[self F1]; //这里是 caller 端的角度,已经传出来了,所以加一个 release
NString* str2 = [self F1]; // 这种有 str2 来接,所以会先帮 str2 加一个 retain,
再帮函式的传回值加一个 release, 两个刚好对消, ref count 不变
如果一切像我想的这么完美,那应该用不到 autorelease
我是这么希望的啦