假设有如下两个函数:
int priority();
void processWidget(std::shared_ptr<Widget> pw, int priority);
将Widget视为资源,我们在调用processWidget是如下调用是不行的processWidget(new Widget, priority())。这样会编译报错,原因很简单,因为把一个指针传递给了一个对象,而这个对象内部没有隐式转换函数。
那么下面这种调用方式是否可以呢?
processWidget(std::shared_ptr<Widget>(new Widget), priority());
从语法的角度是没有问题的,但是C++编译器在编译processWidget函数体前,会执行三步操作,1)new一个Widget对象 2)调用share_ptr类的构造函数 3)调用priority函数。C++编译器不像java和C#编译器那样可以对这几步操作确定顺序,C++编译器有可能会进行优化,当调用priority函数的执行顺序在第二步的时候,就有可能发生内存泄漏问题。因为在执行priority的时候可能发生异常,一旦发生了异常,new出来的指针就不能被放到智能指针对象内,达不到想要的目的。
解决办法也很简单,代码如下:
std::shared_ptr<Widget> pw(new Widget);//将这个语句单独出来
processWidget(pw, priority());