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

Effective C++ 中文版 第三版》读书笔记

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

proToby(std::tr1::shared_ptr<Widget>(new Widget), priority());

在调用 proToby 之前,编译器必须创建代码,做以下三件事:

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

C++ 编译器会以什么样的顺序完成这些事情呢?弹性很大。这和其他语言如 Java 和 C# 是不同的,后两者总是以特定的次序完成函数参数的构造。可以确定的是 “new Widget” 一定执行于 tr1::shared_ptr 构造函数被调用之前,因为这个表达式的结果还要被传递作为 tr1::shared_ptr 构造函数的一个实参,但是对调用 priority 则可以排在第一、第二或者第三位执行。若编译器,恰巧把调用 priority 排在了第二位。最终获得这样的操作序列:

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

现在想一个问题:万一对 priority 的调用导致异常,会发生什么事?此时,“new Widget” 返回的指针将会遗失,因为他未被置入 tr1::shared_ptr 内,后者是我们用来期盼用来方位资源泄漏的武器。但是从这个可能的情况中,我们发现:在对 proToby 的调用过程中可能引发资源泄漏,因为在“资源被创建(经由 “new Widget”)”和“资源被转换为资源管理对象”两个时间点之间有可能发生异常干扰。

避免的办法:使用分离语句,分别写出(1)创建 Widget,(2)将它置入一个智能指针内,然后再把那个智能指针传给 proToby:

std::tr1::shared_ptr<Widget> pT(new Widget);
proToby(pT,priority());

这样之所以可行,因为编译器对于“跨越语句的各项操作”没有重新排列的自由(只有在语句内他才有这个自由)。

** 请记住: **
以独立语句将 newed 对象存储于(置入)智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 再读高效c++,颇有收获,现将高效c++中的经典分享如下,希望对你有所帮助。 1、尽量以const \enum\i...
    橙小汁阅读 1,246评论 0 1
  • 1. 让自己习惯C++ 条款01:视C++为一个语言联邦 为了更好的理解C++,我们将C++分解为四个主要次语言:...
    Mr希灵阅读 2,864评论 0 13
  • 3 资源管理 所谓资源就是,一旦用了它,将来必须还给系统。C++程序中最常使用的资源就是动态分配内存(如果分配内存...
    暗夜望月阅读 414评论 0 0
  • 原作者:Babu_Abdulsalam 本文翻译自CodeProject,转载请注明出处。 引入### Ooops...
    卡巴拉的树阅读 30,178评论 13 74
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,540评论 1 51