您的位置:首页 > 编程语言 > C语言/C++

<<Effective C++>>笔记3

2012-12-23 14:17 471 查看
Chapter 3 ResourceManagement

Item 13: 1、To prevent resource leaks, use RAII objects(智能指针) that acquire resource in their constructors and release them in their destructors.

当将delete语句写入某个函数的时候,因为可能在delete语句之前出现异常或者return而导致函数退出,使得资源没有释放。并且就算现在没有这种情况,代码在后期也有维护的可能,维护的时候不注意全局就加入了return怎么办?

所以为了防止资源泄露(尤其是工厂函数返回的句柄),将资源由某个对象来管理,在该对象的析构函数中释放资源。

2、Two commonly useful RAII classes are tr1::shared_ptr and auto_ptr. tr1::shared_ptris usually the better choice, because its behavior when copied is intuitive.Copying an auto_ptr sets it to null.

std::auto_ptr<指向类型>:只能有一个auto_ptr指向对象,auto_ptr1=auto_ptr2,如此auto_ptr2为null

使用auto_ptr时要小心,其解决的是在堆栈上使用指针引用一个对象后的释放问题。不要误用,不可将其置入容器(因为元素放入容器的时候是通过复制实现的),也不能通过其引用一个对象数组等等。auto_ptr有诸多问题,新标准不推荐使用,建议使用unique_ptr。

std::tr1::shared_ptr<指向类型>是一种引用计数型(reference-counting)智能指针,所以可以有多个shared_ptr引用同一对象。当所有的shared_ptr都析构的时候,资源释放。

!!一定要注意智能指针析构函数中调用的是delete而不是delete [ ],所以无法用智能指针直线动态分配数组或者是string。另外养成习惯,因为[ ]和vector易混淆,如果决定用STL或者template风格的C++,那么就尽可能避免使用[ ],而不要纠结于哪个效率更高。

Item 14: 1、Copying an RAII object entails copying the resource it manages, so the copying behavior of the resource determines the copying behavior of the RAII object.

RAII(Resource Acquisition Is Initialization,资源取得是便是初始化时机)有一条准则:资源在构造函数中取得,在析构函数中释放。

每一个RAII的作者都应当考虑一个问题:如何处理RAII对象复制的问题。有四个选择:

1)当复制对RAII对象没有意义的时候可以选择禁止复制,方式就是复制控制声明为私有,或者直接由Uncopyable类进行私有继承。

2)将RAII对象设计为引用计数指针,一般包含一个tr1::shared_ptr作为成员变量就可以实现了。但是tr1::shared_ptr默认的是当使用计数为0的时候delete资源,但是有的时候使用计数为0时,需要的操作并不是delete,幸好tr1::shared_ptr有一个可选参数(第二个参数,第一个参数为指针)可以用作指定当计数为0的时候需要调用的函数。

3)深度复制,每个对象都保留一个副本,这个就好比是值类型。

4)改变资源的所有权,像auto_ptr一样。

一般都是在第一种和第二种之间进行选择。

2、Common RAII class copying behaviors are disallowing copying and performing reference counting, but other behaviors are possible.

Item 15:1、APIs often require access to raw resource, so each RAII class should offer a way to get at the resource it manages.

一般就是采用get()函数,智能指针中都有get函数,返回的是智能指针对象所包含的原始指针。

如果提供隐式转换的话,容易导致错误。不建议使用隐式转换,因为用户接口最好设计成容易用对难以用错的形式。

2、Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.

Item 16: If youuse [ ] in a new expression, you must use [ ] in the corresponding delete expression. If you don’t use [ ] in a new expression, you must not use [ ] in thecorresponding delete expression.

Item 17:Store newed objects in smart pointers in standalone statements. Failure to do thiscan lead to subtle resource leaks when exceptions are thrown.

书中的例子就是:

ProcessWidget(std::tr1::shared_ptr<Widget>pw(newWidget), priority());

异常会打断正常的执行流程,这是仅次于多线程的可怕东西。

C++的函数调用次序也是必须关注的内容。不要再一条语句中做过多的事情。不要写过于复杂的表达式。不要担心本可以写在一行的代码分成多段会影响执行性能,要多编译器有信心。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: