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)两步紧紧绑定在一起。