1

作者:LogM

本文原载于 https://segmentfault.com/u/logm/articles,不允许转载~

3. 资源管理

  • 3.1 条款13:使用"资源管理类"管理资源

    • 对于 new 出来的对象,某些意外情况下 delete 没有被执行(代码遗漏、鲁棒性低或者出现异常),导致资源泄漏。作者建议使用智能指针管理 new 出来的对象。
    • auto_ptr在拷贝或者赋值时,新指针获得资源拥有权,旧指针变为null。
    std::auto_ptr<Investment> pInv1(createInvestment());  //pInv1获得资源拥有权
    std::auto_ptr<Investment> pInv2(pInv1);  //pInv2获得资源拥有权,pInv1变null
    pInv1 = pInv2;   //pInv1获得资源拥有权,pInv2变null
    • shared_ptr使用计数的方式来确定有哪些指针在使用该资源,计数为0释放资源。它的拷贝和赋值则没有auto_ptr的那个问题。
  • 3.2 条款14:在资源管理类中小心拷贝行为

    • 接3.1,在某些不适用"智能指针"的场景,需要自定义"资源管理类"来管理资源,作者建议需要考虑下这个类的拷贝和赋值。
  • 3.3 条款15:在"资源管理类"中提供对原始资源的访问

    • 在3.1,我们使用智能指针管理对象,此时指针类型是std::auto_ptr<Investment>,但如果有个函数需要类型为Investment*的参数怎么办呢?
    • 智能指针有.get()函数可以显式转换成原始指针;它们也重载了operator->operator*,可以隐式转换。
    • 类似的,自定义的"资源管理类"也需要考虑显示转换和隐式转换,提供对原始资源的访问。
  • 3.4 条款16:成对使用new和delete时要采取相同形式

    • 简单来说,就是new出来的对象要用delete释放,new []出来的对象要用delete []释放。
    • new出来的对象如果使用delete []释放,将导致未定义的行为;new []出来的对象如果用delete释放,很可能只释放了数组的第一个元素。
  • 3.5 条款17:以独立语句将对象置入智能指针

    • //假设有下面这个函数,它有两个参数,调用该函数时,会做下面三件事:
      //a. 调用new Widget
      //b. 执行shared_ptr的构造
      //c. 执行priority()
      //
      //执行顺序是未定义的,可能为a->b->c,也可能a->c->b等等。注意,当顺序为a->c->b,且priority()抛出异常时,资源泄漏。
      processWidget(std::shared_ptr<Widget>(new Widget), priority());
      
      //解决方法:别偷懒,写成两句话
      std::shared_ptr<Widget> pW(new Widget);
      processWidget(pW, priority());

LogM
85 声望18 粉丝