Effective C++ —— 资源管理(三)

条款13 : 以对象管理资源

  假设有如下代码:

Investment* createInvestment();   //返回指针,指向Investment继承体系内的动态分配对象,调用者有责任删除它

void func()
{
    Investment* pInv = createInvestment();   //调用factory函数
    .....
    delete pInv;      //释放pInv所指对象
}

  上述代码可能出现如下问题导致无法删除pInv指针所指对象,出现资源泄露。

  (1)“.....”区域内一个过早结束的return语句;

  (2)delete动作位于某个循环内,而该循环由于某个continue或goto语句过早结束;

(3)“.....”区域内语句抛出异常;

解决方案:把资源放进对象内,我们便可倚赖C++的“析构函数自动调用机制”确保资源被释放。标准程序库提供的auto_ptr正是针对这种形势而设计的特制产品。auto_ptr是个“类指针(pointer-like)对象”,也就是所谓“智能指针”,其析构函数自动对其所指对象调用delete。如下:

void func()
{
    std::auto_ptr<Investment> pInv (createInvestment());
    .....   // 调用factory函数,经由auto_ptr的析构函数自动删除pInv
}

解析:

  1. 获得资源后立刻放进管理对象内。实际上,“以对象管理资源”的观念常被称为“资源取得时机便是初始化时机”(Resource Acquisition Is Initialization;RAII)。每一笔资源都在获得的同时立刻被放进管理对象中。
  2. 管理对象运用析构函数确保资源被释放。即便析构抛出异常,条款08也已经给出解决方案。

这里简单介绍一下“智能指针”:

  auto_ptr采用“所有权”方式管理对象,也即对于auto_ptr的赋值、复制操作将直接交割对象的所有权,所以一定注意不要让多个auto_ptr同时指向同一个对象。

  auto_ptr的替代方案是“引用计数型智慧指针”(reference-counting smart pointer;RCSP),其也是一个智能指针,持续追踪共有多少对象指向某笔资源,并在无人指向它时自动删除该资源。TR1的tr1::shared_ptr(条款54)就是个RCSP。上述代码可修改如下:

void func()
{
    .....
    std::tr1::shared_ptr<Investment> pInv (createInvestment());
    .....   // 调用factory函数,经由shared_ptr的析构函数自动删除pInv
}

注:上述auto_ptr和tr1::shared_ptr只不过是“以对象管理资源”在本条款中所使用的例子。同时,createInvestment返回“未加工指针”(raw pointer)简直是对资源泄漏的一个死亡邀约,其一,调用者极易在这个指针身上忘记调用delete;其二,即使想使用智能指针,也有可能会忘记将createInvestment的返回值存储于智能对象内。所以,条款18提供了一个解决方法:令createInvestment返回一个智能指针。如:

std::tr1::shared_ptr<Investment> createInvestment();

这便强迫客户将返回值存储于一个tr1::shared_ptr内。

故而:

  1. 为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。

  2. 两个常被使用的RAII classes分别是auto_ptr和tr1::shared_ptr。后者通常是较佳选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向Null。

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

  假设有如下代码

编译器可以暗自为class创建default构造函

时间: 2024-08-10 19:18:56

Effective C++ —— 资源管理(三)的相关文章

Effective C++ 条款三 尽可能使用const

参考资料:http://blog.csdn.net/bizhu12/article/details/6672723      const的常用用法小结 1.用于定义常量变量,这样这个变量在后面就不可以再被修改     const int val = 90;      val = 100;   错误 2. 保护传参时参数不被修改,如果使用引用传递参数或按地址传递参数给一个函数,在这个函数里这个参数的值若被修改, 则函数外部传进来的变量的值也发生改变,若想保护传进来的变量不被修改,可以使用const

《Effective Java 第三版》新条目介绍

前言 从去年的3月份起我就在开始读<Effective Java 第二版>,当然,我读的是中文版的:可能是我理解能力还不行,对于书中的内容总是感觉理解困难:就拿第一章的内容「创建和销毁对象」来说吧,这是我读的次数最多的一章,想必原因大家也是明白的,每次我读不下去的时候,我就从头开始读,所以,现在我对这本书的第一章是最为熟悉的了.后来,有一次我上网看到有网友说这本书确实和绝大部分的翻译书籍一样,对于有些原文中的内容翻译的不是很流畅,所以会导致阅读的人感觉难以理解:于是,我就斗胆下了本英文的原版来

Effective C++ 笔记三 资源管理

条款13:以对象管理资源 许多资源被动态分配于heap内而后被用于单一区块或函数内.它们应该在控制流离开那个区块或函数时被释放.标准程序库提供的auto_ptr正是针对这种形式而设计的特制产品.auto_ptr是个类指针对象,也就是智能指针,其析构函数自动对其所指对象调用delete. 以对象管理资源的两个想法:获得资源后立刻放进管理对象内:管理对象运用析构函数确保资源被释放. 若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的

Effective C++笔记(三):资源管理

参考:http://www.cnblogs.com/ronny/p/3745098.html 资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,       无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统.       条款13:以对象管理资源 当我们向系统申请资源后,一定要记得释放,不然就容易发生内存泄漏,但是意识到这样一件事并不是很容易 解决方法是我们把指针放在一个资源管理的类里,让类对象在生命结束的时候,会自动调用析构函数,

C++学习书籍推荐《Effective C++ 第三版》下载

百度云及其他网盘下载地址:点我 编辑推荐 <Effective C++:改善程序与设计的55个具体做法(第3版)(中文版)(双色)>前两个版本抓住了全世界无数程序员的目光.原因十分明显:Scott Meyers极富实践意义的C++研讨方式,描述出专家用以产出干净.正确.高效代码的经验法则和行事法则--也就是他们几乎总是做或不做的某些事.<Effective C++:改善程序与设计的55个具体做法(第3版)(中文版)(双色)>一共组织55个准则,每一条准则描述一个编写出更好的C++的

Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 3. 使用私有构造方法或枚类实现Singleton属性 单例是一个仅实例化一次的类[Gamma95].单例对象通常表示无状态对象,如函数(条目 24)或一个本质上唯一的系统

Effective Java 第三版——10. 重写equals方法时遵守通用约定

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 10. 重写equals方法时遵守通用约定 虽然Object是一个具体的类,但它主要是为继承而设计的.它的所有非 final方法(equals.hashCode.toStr

Effective Java 第三版——12. 始终重写 toString 方法

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 12. 始终重写 toString 方法 虽然Object类提供了toString方法的实现,但它返回的字符串通常不是你的类的用户想要看到的. 它由类名后跟一个"

Effective Java 第三版——14.考虑实现Comparable接口

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. ?14.考虑实现Comparable接口 与本章讨论的其他方法不同,compareTo方法并没有在Object类中声明. 相反,它是Comparable接口中的唯一方法.