effective c++条款17:以独立语句将newed对象置入智能指针
程序员文章站
2024-02-28 23:41:28
...
假设有这么一个函数process,它接收一个MyClass类型的指针与 一个函数,如果按下面的方式调用:
#include <iostream>
#include <memory>
using namespace std;
class MyClass
{
public:
MyClass(){}
~MyClass(){}
};
void FunMyClass()
{
//...
}
void Process(std::tr1::shared_ptr<MyClass> pM, void funMyClass())
{
//...
}
int main(void)
{
Process(new MyClass, FunMyClass);
return 0;
}
这是错误的,因为智能指针shared_ptr的构造函数被声明为explicit,也就是不支持隐式转换,所以我们要显示的对其进行转换:
Process((std::tr1::shared_ptr<MyClass>)(new MyClass), FunMyClass);
我们之所以使用智能指针是为了防止资源泄漏,但是这样调用还有可能导致隐患的,为什么呢?
在调用函数Process之前,编译器需要先构造出函数的参数,对于Process函数来说,它需要做三件事:
1. 调用FunMyClass;
2. new MyClass;
3. 调用shared_ptr的构造;
对于java,C#等语言,参数构造的顺序是固定的,然而对于c++来说,唯一确定的就是new MyClass会先于shared_ptr的构造,所以如果参数构造的顺序如下:
new MyClass→调用FunMyClass→调用shared_ptr的指针
那么一旦FunMyClass抛出了异常,那么new的空间不会被shared_ptr接收到,导致资源泄漏。
解决方法很简单:
std::tr1::shared_ptr<MyClass> pm(new MyClass);
Process(pm, FunMyClass);
这样资源就不会泄露了。
上一篇: 994.腐烂的橘子。1星
下一篇: xml与Java对象的转换详解