“所谓资源就是,一旦用了它,将来必须还给系统。如果不是这样,糟糕的事情会发生。C++程序中最常使用的资源就是动态分配内存(如果你分配内存却从来不曾归还它,会导致内存泄漏),但内存只是你必须管理的众多资源之一。其他常见的资源还包括问见面暑期(file descriptors)、互斥锁(mutex locks)、图形界面中的字型和笔刷、数据库连接、以及网络sockets。不论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统。”
13 Use objects to manage resources
- 由于
auto_ptr
被销毁时自动删除它所指之物,所以一定要注意别让多个auto_ptr
同时指向同一个对象; - 通过
copy
构造函数或copy assignment
操作符复制auto_ptr
,被复制对象会变成null,而复制所得的指针将获取资源的唯一拥有权; auto_ptr
和tr1::shared_ptr
两者都在其析构函数内做delete
而不是delete[]
动作。这就意味着,在动态分配而得的array
身上使用auto_ptr
或tr1::shared_ptr
是错误的(虽然可以通过编译);
14 Think carefully about copying behavior in resource-managing classes
- 复制RAII对象必须一并复制它所管理的资源,所以资源
copying
行为决定RAII对象的copying
行为; - 普遍而常见的
RAII class copying
行为是:禁止copying
操作,施行引用计数法(shared_ptr
思想),复制管理对象时也复制所管理的资源(深度copy
),或者是转移底部资源(auto_ptr
思想);
15 Provide access to raw resources in resource-managing classes
APIs
往往要求访问原始资源(raw resources),所以每个RAII class
应该提供一个”取得其所管理的资源”的办法;- 显示转换比较安全,隐式转换对客户比较方便;
相关博客:【1】
16 Use the same form in corresponding uses of new and delete
- 如果在
new
表达式中使用[]
,那么释放内存的时候也一定要用delete []
。如果在new
表达式中未使用[]
,那么在相应的delete
表达式中也不要使用[]
。 - 尽量不要对数组形式做
typedefs
动作;
17 Store newed objects in smart pointers in standalone statements
- 以独立语句将newed对象存储于智能指针中。如果不这样做,一旦异常被抛出,有可能导致难以觉察的资源泄露。
- 编译器对于“跨语句的各项操作”没有重新排列的自由,编译器只有在语句内才具有重新排列执行顺序的自由;
//假设有如下函数
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
//错误调用,不能通过编译
processWidget(new Widget, priority());
//错误调用,可以通过编译
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
/*
*错误原因:调用processWidget之前,编译器需要做如下三件事:
*调用priority();
*执行"new Widget";
*调用std::tr1::shared_ptr;
*但是C++编译器不能保证调用顺序正确
*/
//正确使用,因为单独语句内执行顺序固定
std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());