定制删除器的产生:在实现智能指针的过程中,我们需要管理数据的构造以及析构,但不同的数据拥有不同的析构方式,例如文件,new出来的空间等等,在利用模板编程中,我们需要识别不同的数据类型,然后选择合适的删除机制,做到一一对应。
定制删除器的实现利用了仿函数,如果你不知道仿函数的话,可以阅读下面的一小部分。
仿函数:其原理是重载了(),让它可以像函数一样使用。
看一段简单的代码:
#include <iostream>
using namespace std;
template<typename T>
struct Less
{
bool operator()(const T& l, const T& r) //重载operator()
{
return l < r;
}
};
void test()
{
Less<int> less;
cout << less(1, 2) << endl; //如果你不知道前面构建的less对象,那么你不知道它是否是函数还是具体的对象
}
int main()
{
test();
system("pause");
return 0;
}
下面回到我们的重点,利用仿函数实现定制删除器(场景选择为智能指针share_ptr的简单模拟实现)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
template<typename T>
struct Del
{
void operator()(const T* ptr)
{
cout << "delete" << endl;
delete ptr;
}
};
struct Free
{
void operator()(void* ptr)
{
cout << "free" << endl;
free(ptr);
}
};
struct Fclose
{
void operator()(FILE* ptr)
{
cout << "fclose" << endl;
fclose(ptr);
}
};
template<typename T,typename DELTER=Del<T>>
class SharedPtr
{
public:
SharedPtr(T* ptr, DELTER del)
:_ptr(ptr)
, _pcount(new long(1))
{}
SharedPtr(T* ptr)
:_ptr(ptr)
, _pcount(new long(1))
{}
SharedPtr(const SharedPtr<T, DELTER>& p)
:_ptr(p._ptr)
, _pcount(p._pcount)
{
++*_pcount;
}
//现代写法
SharedPtr& operator=(SharedPtr<T, DELTER> tmp)
{
swap(_ptr, tmp._ptr);
swap(_pcount, tmp._pcount);
return *this;
}
传统写法
//SharedPtr& operator=(const SharedPtr<T, DELTER>& tmp)
//{
// if (_ptr != tmp._ptr)
// {
// _Relase();
// _ptr = tmp._ptr;
// _pcount = tmp._pcount;
// ++*_pcount;
// }
// return *this;
//}
~SharedPtr()
{
_Relase();
}
public:
//像指针一样
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
protected:
void _Relase()
{
if (--*_pcount == 0)
{
_del(_ptr);
delete _pcount;
_ptr = NULL;
_pcount = NULL;
}
}
protected:
T* _ptr;
long* _pcount; //引用记数
DELTER _del; //定制删除器
};
void test()
{
SharedPtr<int> sp1(new int(1));
SharedPtr<int> sp4(new int(3));
sp4 = sp1;
SharedPtr<int, Free> sp2((int*)malloc(sizeof(int)* 5), Free());
SharedPtr<FILE, Fclose> sp3(fopen("test.txt","w"), Fclose());
}
int main()
{
test();
system("pause");
return 0;
}
以上就是定制删除器在shared_ptr中的应用,利用仿函数的机制去实现。