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

1、为什么要以独立语句将newed 对象置入智能指针?

考虑以下场景:
假设我们有个函数用来显示处理函数的优先权,另一个函数(processWidget())用来在某动态分配所得的Widget上进行某些带有优先权的处理,函数接口如下:

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

//使用上述函数
processWidget(std::tr1::shared_ptr<Widget> (new Widget), priority ());

这里,我们使用了智能指针shared_ptr,用来管理分配的Widget资源,其目的是为了避免内存泄露。但是考虑一个这个函数的执行过程:

(1)函数调用的过程
  • 第一步:在编译器产生一个processWidget调用代码之前,首先需要确定把即将被传递的各个实参是什么。
  • 第二步:发起函数调用。
(2)解析第一步

在第一步中,由于函数有两个实参,我们需要明确实参的确定顺序,然后C++编译器并不会对实参的确定的顺序有硬性的要求,因此它可能是弹性可变的:

第一个参数:

  • (1)首先:new Widget
  • (2)然后调用智能指针的构造函数,构造一个智能指针对象。这个顺序是确定的。

第二个参数:

  • (3)调用priority()
(3)出现问题的原因

整体而言,(2)的次序一定是在(1)的后面,但是(3)可能在任何位置,假如参数的确定按照下面次序:

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

那么这样,可能会发生内存泄露。因为如果在执行第二步:调用priority时发生异常,此时“new Widget”返回的指针将会遗失,因为它尚未被置入tr1::shared_ptr内,而这个智能指针的存在就是为了防止资源泄漏的。

2、如何解决上述问题?以独立语句将newed 对象置入智能指针

具体做法:

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

也就是,先将智能指针创建好以后,再调用该函数。这样就避免的上述的问题。实际上就是保证,资源在创建出来以后,马上被内含到智能指针对象中,其间不能执行任何语句。也就是保证了上述步骤中,(1)(2)两步紧紧绑定在一起。

原文地址:https://www.cnblogs.com/lasnitch/p/12764179.html