zoukankan      html  css  js  c++  java
  • 条款17:以独立语句将newed对象置入智能指针

    请牢记:

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

    假设有个函数用来处理程序的优先权,另一个函数用来在某动态分配所得的Widget上进行某些带有优先权的处理:

    int priority();    //处理程序优先权的函数
    void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);//该函数在动态分配所得的Widget上进行某些带有优先权的处理。

    调用:

    processWidget(new Widget, priority());     //编译不过!该构造函数是explicit 无法隐式转换为shared_ptr
    

    因此可以写成:

    processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());  //可以编译通过,但是...可能泄露资源。
    

    后果:一旦发生异常,可能资源泄露

    原因:

    在调用processWidget之前,编译器必须创建代码,执行三步:

    (1)调用prority()

    (2)执行"new Widget"

    (3)调用 tr1"shared_ptr构造函数

    但是c++调用顺序跟java和c#不同,不是以特定顺序完成。priority函数的调用有可能在第一、第二或者第三执行。当在第二位执行的情况下:

    (1)执行"new Widget"

    (2)调用prority()

    (3)调用 tr1"shared_ptr构造函数

    若调用prority时发生异常,则"new Widget"返回的指针将会遗失,这样会引发资源泄露。

    解决方案:使用分离语句,分别写出(1)创建Widget,(2)将它置入一个智能指针内,然后再把那个智能指针传给processWidget:

    std::tr1::shared_ptr<Widget> pw(new Widget);    //在单独语句内以智能指针存储newed所得对象
    processWidget(pw, priority()); // 这个动作不会造成泄露

    因为编译器对于”跨越语句的各项操作“没有重新排列的自由(只有在语句内编译器才拥有那个自由度)。

  • 相关阅读:
    Android Button上的文字自动变成大写,如何解决呢?
    如何在IamgeButton上面添加文字
    C语言之实现函数返回一个数组,以及选择排序,还有折半查找。这是同学的一个作业。。。
    解决android:background背景图片被拉伸问题
    service&thread
    MS SQLServer Update语法和实例
    ztree2.6给菜单增加title提示信息[转]
    UltraEdit-14.10.0.1024版本语法着色配置
    linux下c++动态库的生成及使用
    c++动态库与静态库
  • 原文地址:https://www.cnblogs.com/lwenwen/p/3474501.html
Copyright © 2011-2022 走看看