C++11中的智能指针基于RAII,帮助程序员在复杂的程序流程下解决内存泄漏的问题。除了“堆上分配的内存忘了释放”外,实际应用中也常面临“打开的文件忘了关闭”的问题,尤其是在操作由std::fopen得到的FILE *句柄时。而智能指针通过指定自定义deleter同样可用于及时关闭已经打开的文件上。
以std::unique_ptr为例,可以看到它的定义为:
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
第一个模板参数T指定了指针的类型,如unique_ptr<T>实际上管理的是一个T *指针。而第二个可选模板参数Deleter用于指定一个删除方法的类型,一般来说,Deleter需要是一下三种情形之一:
- 函数对象
- 函数对象的左值引用
- 函数的左值引用
这个删除方法定义了该指针失效时对指针的操作,其唯一调用参数为指针本身,例如与std::malloc对应的std::free方法。这和std::fclose声明的参数列表是兼容的。因此,可以通过下面的形式,将std::fclose作为std::unique_ptr的删除方法,实现自动关闭已打开的FILE *的效果:
{
std::unique_ptr<FILE, decltype(std::fclose) *> file(std::fopen("test.txt", "r"), std::fclose);
//do something with file.get() here
}//file is closed here