定制删除器
shared_ptr的另一种形式的构造函数share_prt(Y* p, D d), 参见boost shared_ptr基本用法介绍它的第一个参数是要被管理的指针,而第二个删除器参数d则告诉shared_ptr在析构时不是使用delete来操作指针p,而是要用d来操作,即把delete p 换成 d (p)。
在这里d可以是一个函数对象,也可以说一个函数指针,只要它能够像函数那样被调用,使得d ( p )成立即可。对删除器的要求是它必须可以拷贝,行为也必须也像delete那样,不能抛出异常。
为了配合删除器的工作,shared_ptr提供了一个自由函数get_deleter(shared_ptrconst&p),它能够返回删除器的指针。
有了删除器的概念,我们就可以用shared_ptr实现管理任意的资源。
假如我们有一组操作socket的函数,使用一个socket_t类:
class socket { ... };
socket_t* open_socket()
{
cout << "open_socket" << endl;
return new socket_t;
}
void close_socket(socket_t *s)
{
cout << "close_socket" << endl;
...//其他操作,释放资源
}
socket_t的资源释放函数就是close_socket();它符合shared_ptr对删除器的定义,可以用shared_ptr这样释放资源。
socket_t*s=open_socket();
shared_ptr<socket t>p(s,close_socket); //传入删除器
在这里删除器close_socket0是一个自由函数,因此只需要把函数名传递给 shared_ptr 就可以了。在函数名前也可以加上取地址操作符&,效果是等价的:
shared_ptr<socket_t>p(s,&close_socket); //传入删除器
这样我们就使用shared_ptr 配合定制的删除器管理了socket 资源。当离开作用域时,sharedptr 会自动调用 close_sock- etO函数关闭 socket,再也不会有资源遗失的担心。
再例如,对于传统的使用struct FILE的C文件操作,也可以使用shared_ptr配合定制删除器自动管理,像这样
shared_ptr<FILE>
fp(fopen("./1.txt","r"),fclose);
当离开作用域时,shared_ptr 会自动调用fclose()函数关闭文件。
shared_ptr的删除器在处理某些特殊资源时非常有用,它使得用户可以定制,扩展shared_ptr的行为,使shared_ptr 不仅仅能够管理内存资源,而是能成为一个"万能"的资源管理工具。