【复读EffectiveC++17】条款17:以独立语句将newed对象置入智能指针

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

此条款,依然是针对智能指针的补充,内容分为两个部分:

  • 有什么问题
  • 怎么解决

一、有什么问题

取原书的例子:
写一个函数,用来揭示程序处理的优先权。
再写一个函数,用来在某动态分配得到的Widget上进行某些带有优先权的处理:

int priority();

//依据”以对象管理资源“的原则,决定对动态分配的来的Widget运用智能指针,这里采用trl::shared_ptr
void processWidget(std::trl::shared_ptr<Widget> pw,int priority);

现在考虑调用processWidget,这里会出现两个问题。

1、问题一

processWidget(new Widget,priority());

但这个函数调用不能通过编译,因为在tr1::shared_ptr构造函数需要一个原始指针,但该构造函数是个explicit构造函数,无法进行隐式转换,也就是不能将“new Widget”返回的原始指针直接隐式转换为processWidget需要的tr1::shared_ptr。

2、问题二

因此用下面会通过编译的代码:

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

虽然这样能顺利通过编译,并且使用了”以对象管理资源“,但这样调用却可能出现资源泄露。

在调用processWIdget之前,准备参数会做三件事:

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

但这里我没有对三件事进行有序排列,是因为存在一个问题,即C++编译器会以什么样的次序完成这些事情呢?

这里可以确定 执行 new Widget 一定先于 调用 trl::shared_ptr 构造函数 被调用,因为这个表达式的结果还要被传递作为trl::shared_ptr构造函数的一个实参。

但是对 调用 priority 是排在第一或第二或第三执行,就不一定了。

假设其排在第二执行,总体操作顺序将会是:

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

更巧的是,如果在这个过程中,对调用priority出现异常,会让第三步的调用trl::shared_ptr构造函数没有发生,new Widget调用后返回的指针不会被置入trl::shared_ptr内,造成用来防止资源泄露的机制失效。

二、怎么解决

解决方法很简单:

  • 创建Widget,将它置入一个智能指针内,然后将那个智能指针传给processWidget;

代码如下:

std::trl::shared_ptr<Widget> pw(new Widget)//以智能指针存储newed所得的对象作为一条单独的语句
processWidget(pw,priority());//这个调用动作不会造成资源泄露

三、总结

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

相关推荐

  1. 13:用对象管理资源(智能指针

    2024-04-14 20:58:05       40 阅读
  2. effective c++ 笔记 13-18

    2024-04-14 20:58:05       46 阅读
  3. C++11智能指针

    2024-04-14 20:58:05       37 阅读
  4. 【C/C++ 14】C++11智能指针

    2024-04-14 20:58:05       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-14 20:58:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-14 20:58:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-14 20:58:05       82 阅读
  4. Python语言-面向对象

    2024-04-14 20:58:05       91 阅读

热门阅读

  1. centos7升级openssl3.0.13版本

    2024-04-14 20:58:05       36 阅读
  2. vue2隐藏浏览器右侧滚动条

    2024-04-14 20:58:05       33 阅读
  3. Redis提供两种持久化机制RDB和AOF机制

    2024-04-14 20:58:05       34 阅读
  4. 【Linux】SCP命令:文件传输的简易指南

    2024-04-14 20:58:05       31 阅读