Effective C++ 炒冷饭 – Item 13 通过对象来管理资源

Effective C++ 炒冷饭 – Item 13 通过对象来管理资源

[原创文章欢迎转载,但请保留作者信息]
Justin 于 2009-12-07

因为准备英文考试以及工作变动的事情,已经隔了很久没有读书,也就很久没有记录笔记了。学习可以被打断,但是不能终止。嗯不废话了。继续来读圣贤书。

Item13 被安排在第三章“资源管理”的第一位,所以讲得也很通俗易懂:要利用对象来管理资源(可以是分配出来的内存、互斥量等)。这样做的好处是可以避免因为写代码时的疏忽而导致的资源流失(可以是内存的泄漏,也可能是忘了解锁)。为什么用对象来解决这个问题呢?因为以下两点:

  • 将释放资源的代码放在对象的析构函数中,只要对象被析构,就可以保证资源被完整释放。
  • C++的析构函数自动调用机制(C++’s automatic destructor invocation)能够保证当对象脱离控制时该对象的析构函数被调用(比如一个对象在某函数内部定义,那么在函数执行结束后,这个对象的析构函数会被自动调用以销毁此对象)。

是个好办法,至少对我这样时常丢三落四的人来说是个福音。何况这样的对象大多数情况下不用自己写,auto_ptr(智能指针, smart pointer的一种)就可以胜任。

下面一段代码其实和书上的没有区别,只是为了加深印象

// blah blah
std::auto_ptr < void *>  pMem(AllocAndInitMemory());
// feel free to use pMem
// and no need to bother releasing the memory
// isn't it great?

高亮的部分即说明了auto_ptr的用法,也附带示范了所谓的RAII(Resource Acquisition Is Initialization)。我想这里可以翻译为“资源申请时初始化”,虽然拗口了一些,但至少好理解,也不用再多做解释。
这里的auto_ptr就像是个陪女友逛街的可怜家伙,女朋友(用户)说要什么,auto_ptr就乖乖的去买来(申请),想要用的时候就赶紧拿出来给女友用,哪怕她忘了曾经买了某件衣服,auto_ptr还是会老老实实地送回家里,不用担心会弄丢或是搞脏。嗯,有点做上帝的感觉吧?

不过,没有什么是十全十美的。大师马上就说到了用对象管理资源的问题,好吧,应该说是需要注意的地方:
首先不能用一个以上的对象,比如说auto_ptr,管理同一个资源。这个很好理解,就像一个漂亮的女孩子脚踏多条船(同时定义了多个auto_ptr),但是她必须要小心,不能让多个对象参加同一个约会:今天逛街的时候喊上了小张就不能叫小王,明天一起吃饭如果约了小李就别再和小赵定时间:一个资源一次只能让一个对象来管理。
这样的规则用在auto_ptr上就是书中奇怪的“=”行为:两个auto_ptr对象A和B,A=B运算的结果是A接管了B管理的资源,B指向的是null。(如果记不起来了,具体代码见书)这样的行为很像是传递:小李陪女朋友逛完街后,送她到人民广场,在那里小陈约好了和她一起看电影。到了人民广场之后小陈搂着女人开心的走了,只剩下小李一个孤单的背影,杯具啊杯具……

为了避开这种尴尬且极易被误解的“=”操作,出现了以shared_ptr为代表的reference-counting smart pointer(RCSP)(计数智能指针?)。它们可以“共事一夫”,由一个公用的reference counter来计数,某个shared_ptr在准备抛弃一个资源时先参考reference counter的值,如果非零,说明还有其他的“姐妹”在罩着资源,不需要也不可以释放该资源;如果值为零,说明当前只有她一个人了,于是真正的担当起smart pointer的责任:释放资源。

最后作者貌似意识到写得有点跑题,就提醒了一把:重点不在于是用auto_ptr还是shared_ptr还是其他的什么东东,而是要领会精神——使用对象来管理资源。比如说用string对象来管理一个字符串而不是手工申请一片内存然后用个指针“吧唧”粘上去就开始用了。

你可能感兴趣的:(Effective C++ 炒冷饭 – Item 13 通过对象来管理资源)