假设有如下两个函数:

int priority();
void processWidget(std::tr1::shared_ptr<Widget>pw, int priority);

对processWidget的调用如下:

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

编译器产出一个processWidget调用码之前,必须首先核算即将被传递的各个实参。上述第一实参由两部分组成:

  • 执行"new Widget"表达式
  • 调用tr1::shared_ptr构造函数

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

  • 调用priority
  • 执行"new Widget"
  • 调用tr1::shared_ptr构造函数

C++编译器以什么样的次序完成这些事情弹性很大。可以确定的是"new Widget"一定执行于tr1::shared_ptr构造函数被调动之前。如果编译器选择第二顺位执行它,最终获得这样的操作序列:

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

一旦对priority的调用导致异常,“new Widget”返回的指针将会遗失,从而导致内存泄露。

避免这类问题的办法是使用分离语句:分别写出(1)创建Widget,(2)将它置入一个智能指针内,然后再把那个智能指针传给processWidget(因为编译器对“跨越语句的各项操作”没有重新排列的自由):

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

《Effective C++》——条款17:以独立语句将newed对象置入智能指针的更多相关文章

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

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

  2. Effective C++(17) 以独立语句将newed对象置入智能指针

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

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

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

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

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

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

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

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

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

  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. 002-IP地址及分类以及子网掩码

    一.概述 IP地址是一个4段2进制码组成的,每一段二进制码有8位,共32位二进制数.占用4个字节. IP地址是指互联网协议地址(Internet Protocol Address,又译为网际协议地址) ...

  2. boost之正确性和测试

    BOOST_ASSERT在debug模式下有效. #include <iostream> #include <boost/assert.hpp> using namespace ...

  3. Python基础(8)_迭代器、生成器、列表解析

    一.迭代器 1.什么是迭代 1 重复 2 下次重复一定是基于上一次的结果而来 l=[,,,] count= while count < len(l): print(l[count]) count ...

  4. win10 chrome 调试

      下载NPAPI版本的flash player: http://www.adobe.com/support/flashplayer/debug_downloads.html#fp13       禁 ...

  5. LDA主题模型三连击-入门/理论/代码

    目录 概况 为什么需要 LDA是什么 LDA的应用 gensim应用 数学原理 预备知识 抽取模型 样本生成 代码编写 本文将从三个方面介绍LDA主题模型--整体概况.数学推导.动手实现. 关于LDA ...

  6. 通过ip得到所在城市,以及城市所在经纬度坐标(监控系统中用的该代码,小航哥)

    监控系统中就是利用的该段代码,实现通过ip得到所在城市,以及城市所在经纬度坐标,最后得以利用echarts实现模拟迁移的效果 api官方介绍: http://lbsyun.baidu.com/inde ...

  7. git在IDEA中的使用

    学习资料: http://blog.csdn.net/autfish/article/details/52513465  (关于提交的讲解) http://blog.csdn.net/ck443870 ...

  8. PAT 天梯赛 L1-043. 阅览室 【STL】

    题目链接 https://www.patest.cn/contests/gplt/L1-043 思路 将每一次 借出和归还 都用 MAP 标记 如果归还的时候 已经被标记过了 那么 ANS ++ 并且 ...

  9. iOS 视图控制器转场动画/页面切换效果/跳转动画 学习

    一 学习 在 UINavigationController 中 push 和 pop 的转场效果  (基于iOS7 以上的转场方式) 经过学习了解到,重点分三块: (1)pushAnimation:  ...

  10. linux常用技巧(资料)

    Linux中查看程序安装位置 如果是rpm的安装,用rpm -ql如果是一般安装 用 whereis 或者 find find /usr -name catalina.out======== 如何查看 ...