欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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);

这样资源就不会泄露了。