问题聚焦:
    使用了资源管理对象(如智能指针),就一定是安全的吗?显然不是。
    资源泄露发生可能在于,在“资源被创建”和“资源被转换为资源管理对象”两个时间点之间有可能发生异常干扰。

看下面这个例子:
//函数说明
int priority();    //揭示处理程序的优先权
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); // 用来在某动态分配所得的Widget上进行某些带有优先权的处理
// 这里对动态分配得来的Widget运用智能指针
// 现在考虑调用processWidget
processWidget(new Widget, priority()); // 显然编译是不通过的,原因是类型不匹配。 // 如果像下面这样调用即可
processWidget(std::tr1::shared_prt<Widget>(new Widget), priority()); // 编译通过

然而令人惊讶的是,上述正确的调用方法,却可能发生资源泄露。
分析:
调用processWidget之前,编译器需要做三件事:
  • 调用priority
  • 执行“new Widget”
  • 调用tr1:shared_ptr构造函数
问题在于:C++编译器是以什么样的次序完成这些事情的呢?
答案是不确定的。
可以确定的是:“new Widget”一定执行于tr1::shared_ptr构造函数被调用之前。
但是对priority的调用则可以排在第一第二或第三的位置。
当priority的调用排在第二的位置时,执行次序如下:
  1. 执行“new Widget”
  2. 调用priority
  3. 调用tr1:shared_ptr构造函数
潜在的问题:如果第二步发生异常,new Widget返回的指针将会遗失。(其实为什么会遗失,这个问题有待验证)
所以,资源泄露发生可能在于,在“资源被创建”和“资源被转换为资源管理对象”两个时间点之间有可能发生异常干扰。

解决的方案:
使用分离语句
std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());
依据在于:编译器对于“跨越语句的各项操作”没有重新排列的自由。

小结:
以独立语句将newed对象存储于智能指针内,如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。
参考资料:
《Effective C++ 3rd》

Effective C++(17) 以独立语句将newed对象置入智能指针的更多相关文章

  1. Effective C++ 条款17 以独立语句将newed对象置入智能指针

      对于函数: int priority(); void processWidget(std::tr1::  shared_ptr<Widget> pw,int priority); 调用 ...

  2. [Effective C++ --017]以独立语句将newed对象置入智能指针

    这一节也比较简单,先假设我们有如下的函数: int foo(); void memFoo(shared_ptr<T> pw, int foo); 现在假设我们要调用memFoo函数: me ...

  3. 条款17:以独立语句将newed对象置入智能指针(Store newed objects in smart pointers in standalone statements)

    NOTE: 1.以独立语句将newed对象存储于智能指针内.如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏.

  4. Effective C++ -----条款17:以独立语句将newed对象置入智能指针

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

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

    请牢记: 以独立语句将newed对象存储于(置入)智能指针内.如果不这样做,一旦异常被跑出来,有可能导致难以察觉的资源泄露. 假设有个函数用来处理程序的优先权,另一个函数用来在某动态分配所得的Widg ...

  6. 《Effective C++》——条款17:以独立语句将newed对象置入智能指针

    假设有如下两个函数: int priority(); void processWidget(std::tr1::shared_ptr<Widget>pw, int priority); 对 ...

  7. 【17】以独立语句将newed对象置入智能指针

    1.为什么? 考虑下面的情况:方法声明为void processWidget(shared_ptr<Widget> pw,int priority). 调用方法 processWidget ...

  8. [EffectiveC++]item17:以独立语句将newed对象置入智能指针

    Store newed objects in smart pointers in standalone statements

  9. 以独立的语句将new对象置入智能指针

    以独立的语句将newed对象置入智能指针: processWidget(std::tr1::share_ptr<Widget>(new Widget) , priority()); 我们在 ...

随机推荐

  1. swift 笔记 (七) —— 关闭

    关闭 封闭件是从包括以下各项的组.它可以在代码被发送"片"... 行,不纠结的定义.继续. swift的闭包,有点像C和Objective-C语言里的 代码块 {--}  闭包能够 ...

  2. 2014ACM/ICPC亚洲区域赛牡丹江站汇总

    球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doub ...

  3. android 之 下载管理器 无论监测在当地的设计思路

    我相信你.让应用市场.或其它下载,想不管是什么地方监测进展情况.而且很好的实现. 这里分享一个相对简单的,并防止内存溢出等..我们用一个引用弱结合View进展更新方法. Map<String, ...

  4. Scriptcase演示程序,现在,他们使用SC多么简单的开发系统

    Scriptcase它内置了一批成熟的业务系统,我们的系统的一部分已经完成和功能微调,在互联网上.检查每个人Scriptcase如何简单可以加速的功能模块的发展. 访问 http://www.phps ...

  5. 前端学习笔记(zepto或jquery)——对li标签的相关操作(三)

    对li标签的相关操作——八种方式遍历li标签并获取其值 $("ul>li").forEach(function(item,index){ alert(index+" ...

  6. 【转】Appium基于安卓的各种FindElement的控件定位方法实践

    原文地址:http://blog.csdn.net/zhubaitian/article/details/39754041#t11 AppiumDriver的各种findElement方法的尝试,尝试 ...

  7. bootstrap标准模板

    <!DOCTYPE html><!--html5定义--> <html lang="en"> <head> <meta cha ...

  8. 搜集朋友写的几篇Android Elf相关的文档

    对android elf的资料学习,多数是在看雪找的资料,另一部分朋友的研究,当然,给他们提议过整理成一系列文章,只是大家工作都太忙,也都没顾上,这里简单整理放上一些pdf的资料,有兴趣的朋友能够看看 ...

  9. 再谈IE的浏览器模式和文档模式

    原文:再谈IE的浏览器模式和文档模式 以前在 “IE8兼容视图(IE7 mode)与独立IE7的区别”一文中曾经涉及过浏览器模式和文档模式,但二者的区别却不甚了了,现在有了新的认识,再补充一下. 1. ...

  10. IOS程序创建view

    在IOS程序中创建view有六种方式 首先创建一个GLViewController类,继承UIViewController. 然后进入GLAppDelegate.m,在- (BOOL)applicat ...