zoukankan      html  css  js  c++  java
  • Effective C++ 精要(第三部分:资源管理)

    条款13:以对象管理资源

    在一个函数中,获取若干资源后,会对这些资源进行若干操作,正确的设计要求我们在函数返回时将资源释放。但是,如果在我们释放资源之前,因为异常或者过早返回导致临时资源没有被释放,就会造成资源泄漏,即使非常小心的添加delete语句,仍然无法避免某个异常发生在delete之前而造成资源泄漏。更可靠的方式是把资源放到对象中,而局部对象会在离开控制区后,C++会自动回收这个临时对象,并自动调用析构函数,这个机制可以保证资源被正确的释放,而这里所说的对象也就是我们常常使用的智能指针: auto_ptr和shared_ptr等。这个条款基于如下两个想法:

    • 获得资源后立刻放进管理对象内:把createInvestment返回的资源被当作auto_ptr和shared_ptr的初值,也就是初始化auto_ptr和shared_ptr,这种代码也被称为“资源获取时便是初始化时”(Resource Acquisition Is Initialization: RAII),当然有时也会将获得的资源拿来赋值某个管理对象,但不论哪一种做法,都要在获取资源后立刻放到管理对象中;
    • 管理对象运用析构函数确保资源被释放:对象离开作用域时自动调用析构函数;

    auto_ptr是不允许Copying行为的例子,而更常用的是shared_ptr的引用计数型的智能指针(Reference Counting Smart Pointer, RCSP),RCSP内部有个计数器统计有多少个对象指向某个资源,并在无人指向资源时,将资源释放;关于Copying的行为,看下面的条款。auto_ptr和shared_ptr内部使用的都是delete,而不支持delete[],所以它们不支持管理数组对象,如果要数组对象,可以使用vector和string代替,如果确实需要,可以考虑Boost的scoped_array和shared_array。

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

    先看一个例子,假设我们有一个Mutex资源,使用lock 和unlock管理这个资源,现在我们要想只用对象来管理这个资源,可以在构造函数里调用lock,在析构函数中调用unlock,目前为止都很好,那如果客户调用了Copy构造函数或者赋值操作符时,会发生什么呢?在我们自己写资源管理类时,一定要明确应该有什么样的行为,下面是一些可用的选择:

    • 禁止复制:上面Mutex的例子就是禁止赋值的典型,如果允许赋值,会有两个对象获取了同一个Mutex,而这就起不到Mutex的作用了。要禁止Copy可以参考条款06;
    • 对底层资源使用“引用计数法”:shared_ptr就是一个很好的例子,而且它还支持定制的“删除器”,而不是固定调用delete;
    • 复制底层资源:也就是深度拷贝了;
    • 转移底部资源的拥有权:auto_ptr的行为;

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

    为了与existing API兼容,我们很多时候都会需要访问原始资源,我们在自己书写资源管理类时就应该提供这个功能。比如auto_ptr和shared_ptr就提供了get()函数来获取原始资源,同时还需要重载指针取值运算符(operator->和operator*),可以隐式转换至底部原始指针。如果嫌调用get()麻烦,可以提供隐式转换函数,这样使用起来就可以在需要底部资源类型时,自动转换,但是也会增加错误的机会,比如,把一个FontHandle f2 = f1;本来是想拷贝一个Font对象,却误操作为将f1隐式转换为底部的FontHandle,然后再复制这个底部资源对象。

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

    这个条款应该是比较好理解的,new了一个数组,却调用delete;或者new了一个对象,却调用delete[],C++会对内存布局产生灾难性的影响。

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

    也就是使用独立语句进行RAII,否则会因为编译器重新排序了语句次序,而在RAII之间插入的语句抛出异常会造成资源泄漏。

  • 相关阅读:
    Sql Server中暂停命令
    优化SQL Sever查询语句的几个要点
    SQL Server 常用日期查询语句
    Android开发环境配置
    java实验报告(实验一)
    java实验报告(实验二)
    学习java的一点体会
    [已解决]求助:vs2003用代码实现excel的设置
    关于webform信息提示框
    DataGrid按钮事件的触发
  • 原文地址:https://www.cnblogs.com/whyandinside/p/2752669.html
Copyright © 2011-2022 走看看