Chapter 3 资源管理
Item 13 用RAII对象管理资源
- 为了防止忘添加delete导致资源泄漏,应该使用RAII对象(比如shared_ptr)来管理需要调用的资源
- shared_ptr和auto_ptr的区别:shared_ptr允许多个指针指向同一块内存而auto_ptr不行,auto_ptr指向对象时实际上会发生对应对象的拷贝(然而现在C++11早就把auto_ptr弃用了,职能转给了unique_ptr, 对象转化调用的是std::move函数而不需要再先拷贝后删除了)
Item 14 拷贝智能指针的对象需谨慎
-
在面对不得不拷贝RAII对象时(书中举例了一个Mutex锁,事务结束时为了让其实现解锁功能而非被删除,将管理它的Lock类对应的管理Mutex的智能指针的删除器定义为一个unlock函数),拷贝对象的拷贝行为将决定其智能指针对象的拷贝行为。
-
一般无法直接拷贝智能指针下的对象,但是可以定义智能指针的其他行为(比如删除器)
Item 15 提供获取资源管理类中资源的方法
- 对于使用指针资源管理资源的类应该定义能获取其资源的方法(比如重载*或者->运算符)
- 考虑设计的功能是否允许参数的隐式转换,如果不希望就给方法加上explicit,但一般来说允许隐式转换对用户更方便
Item 16 正确使用new和delete
new 和 delete 配对使用, 如果你new的是一个数组,那必须用delete[] 而不是delete
(原理:new调用对象的构造函数而delete调用对象的析构函数,单个delete无法判断对象数组的数量,也就是该调用多少个构析函数)
Item 17 构建好智能指针对象再传参
考虑如下情况:
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
对一般对象形参,C++会依据压栈顺序逐步构造,但是如果传入的是个函数,函数的调用顺序将取决于编译器,不一定按照参数列表的顺序。直接在函数中传入智能指针对象做实参,可能会出现以下调用顺序:
- 构造 new Widget
- call priority()
- 调用shared_ptr的构造函数
如果priority()的调用出现了错误,将会导致内存泄漏。
因此建议把widget装进智能指针后再传参,这样priority如果报错的话至少智能指针能帮你把无用对象处理掉。