1.仿函数
首先我们需要知道什么是仿函数。
仿函数:仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
示例:
#include<iostream>
#include<cstdlib>
using namespace std;
class Print
{
public:
void operator()(int n)
{
std::cout << n << std::endl;
return;
}
};
int main()
{
Print print;
print(372);//仿函数
print.operator()(372); //~ 显式调用
return 0;
}
2.简单的利用仿函数实现定制删除器
在这里我们需要对一个智能指针的问题探究,当我们进行资源的处理时。无非是两种资源,一种是文件,一种是堆内存空间,对于文件,我们fopen,然后fclose,对于堆内存,我们会new,也可能会new[],也可能会malloc,当我们释放,当然也就对应着delete,delete[],free。所以在这里当我们使用智能指针的时候,需要让它对于删除器进行操作,比如我们打开一个文件能够让它识别,最后关闭文件。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdlib>
#include<boost/shared_ptr.hpp>
using namespace std;
//利用仿函数实现定制删除器
struct Fclose
{
void operator ()(void *ptr)
{
fclose((FILE *)ptr);
cout << "仿函数fclose" << endl;
}
};
struct Free
{
void operator ()(void *ptr)
{
free(ptr);
cout << "仿函数free()" << endl;
}
};
void test_del_shared_ptr()
{
boost::shared_ptr<FILE> sp(fopen("test.txt", "w"), Fclose());
int *p = (int *)malloc(sizeof(int));
boost::shared_ptr<int>sp1(p, Free());
}
int main()
{
//test1();
test_del_shared_ptr();
system("pause");
return 0;
}
我们使用仿函数,重载了operator(),然后根据这个函数执行操作,在传递的时候,我们根据一个匿名的对象,把这块资源进行正确的管理。
3.模拟实现智能指针的定制删除器
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdlib>
using namespace std;
struct File
{
void operator ()(void *ptr)
{
fclose((FILE*)ptr);
}
};
template<typename T>
struct DefaultDel
{
void operator()(T *ptr)
{
delete ptr;
}
};
template<typename T>
struct Free
{
void operator()(T *ptr)
{
free(ptr);
}
};
template<typename T>
struct DeleteArr
{
void operator()(T *ptr)
{
delete[] ptr;
}
};
template<typename T,typename D=DefaultDel<T>>
class SharedPtr
{
public:
SharedPtr(T* ptr)
:_ptr(ptr)
, _pCount(new int (1))
, _del(D())
{
}
~SharedPtr()
{
release();
}
SharedPtr(SharedPtr<T,D> & sp)
:_ptr(sp._ptr)
, _pCount(sp._pCount)
{
(*_pCount)++;
}
//现代写法
SharedPtr<T,D> operator = (SharedPtr<T,D> sp)
{
std::swap(_ptr, sp._ptr);
std::swap(_pCount, sp._pCount);
}
//传统写法
/*SharedPtr<T,D> operator = (SharedPtr<T,D>& sp)
{
if (this != &sp)
{
release();
_ptr = sp._ptr;
_pCount = sp._pCount;
(*_pCount)++;
}
}*/
T* operator ->()
{
return _ptr;
}
T& operator *()
{
return *_ptr;
}
private:
void release()
{
if (--(*_pCount) == 0)
{
_del(_ptr);
delete _pCount;
_ptr = NULL;
_pCount = NULL;
}
}
private:
T* _ptr;
int* _pCount;
D _del;//所给的删除器类型
};
void test1()
{
SharedPtr<FILE, File> sp(fopen("test.txt", "w"));
SharedPtr<int> sp2(new int(1));
}
int main()
{
test1();
system("pause");
return 0;
}
在这里我们根据不同的类型进行不同的资源释放的方式,在默认用new开辟的情况下,我们采取默认delete释放。