假如我们有这样的函数:
int priority();
void processWidget(std::shared_prt<Widget>pw, int priority);
假如我们这样写:
processWidget(std::shared_prt<Widget>(new Widget), priority());
虽然我们使用对象管理式资源,上述调用却可能泄露资源。
编译器在对processWidget
调用之前,必须先核算即将被传递的各个实参,上面第一个实参是std::shared_prt<Widget>(new Widget)
,第二个实参是priority()
.
std::shared_prt<Widget>(new Widget)
由两部分组成:
1.执行new widget
表达式
2.调用shared_prt
构造函数
于是在调用processWidget
之前,编译器必须创建代码,做以下三件事情:
调用priority
执行new widget
调用shared_prt
构造函数
C++编译器以什么次序完成这些事情呢?这没有保证,我们唯一可以确定的是new widget
一定执行于shared_prt
构造函数被调用之前。
但是对priority
的调用可以排在第一、第二或第三执行。
假如编译器以第二顺位执行它:
1.执行new widget
2.调用priority
3.调用shared_prt
构造函数
万一对priority的调用导致异常,会发生什么事?
这种情况下new widget
返回的指针会遗失,因为它没有被放入shadred_prt
内。
所以说,对processWidget的调用过程中可能引发资源泄露,因为在资源被创建和资源被转换为管理对象两个时间点之间有可能发生异常干扰。
解决这种问题的方法很简单:
std::shared_prt<Widget>p(new widget);
processWidget(p, priority());
通过使用分离语句,这样就不会造成泄露了。
总结:
以独立语句将newed对象存入智能指针内,如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄露。