0%

3 资源管理

条款13:以对象管理资源

  1. 以对象管理资源的观念常被称为“资源取得时机便是初始化实际”(Resource Acquisition Is Initialization; RAII)。在获得的同时立刻被放进管理对象中。auto_ptrs有个不寻常的性质:若通过copy构造函数或copy assignment操作符复制,它们就会变成null,而复制所得的指针将取得资源的唯一拥有权,并在析构函数中释放资源。
  2. auto_ptr的替代方案是“引用计数型智能指针”(reference-counting smart pointer;RCSP)。它提供的行为类似垃圾回收garbage collection)。

条款14:在资源管理类中小心copying行为???

  1. 复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
  2. 普遍而常见的RAII class copying行为是:抑制copying、施行引用计数法(reference counting)。

条款15:在资源管理类中提供对原始资源的访问

  1. 除非发誓永不录用APIs,否则只得绕过资源管理对象(resource-managing objects)直接访问原始资源raw resources)。要将RAII class对象转换为其所包含的原始资源。有两个做法:显式转换和隐式转换。前者通过get成员函数可获得指针;后者可行是因为RAII重载了指针取值pointer dereferencing)操作符(operator->和operator*),它们允许隐式转化至底部原始指针。

条款16:成对使用new和delete时要采取相同形式

  1. 当你使用new,有两件事发生。第一,内存被分配出来(operator new);第二,针对此内存会有一个(或更多)构造函数被调用。当你使用delete,也有两件事发生;针对此内存会有一个(或更多)析构函数被调用,然后内存被释放(operator delete)。
  2. new时使用[],必须在相应调用delete时也使用[]。对于喜欢对数组形式做typedef动作的人,最好不要这样做,而C++ STL标准库中的容器templates,可将数组需求降至最低。

条款17:以独立语句将newed对象置入智能指针

对于processWidget(std::shared_ptr<Widget>(new Widget), priority());这行代码可以通过编译,然而上述调用可能泄露资源。因为它的执行顺序可能时

  1. 执行“new Widget”
  2. 调用priority删除
  3. 调用std::shared_ptr构造函数

      万一对priority的调用导致异常,“new Widget”返回的指针将会丢失,因为尚未置入std::shared_ptr内。解决方法是使用独立语句将创建Widget和置入指针两个步骤分割开来:

1
2
std::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());