函数对象与函数指针
大约 4 分钟
函数对象与函数指针
一、函数对象与函数指针
函数对象: 拥有operator()
重载函数的对象即函数对象,函数对象,但在C++里为函数对象。
问题一:什么是函数对象呢?
例如:我们C语言进行函数调用与C++中两个函数调用。

看起来它们好像一模一样(),但是这里我们就把()运算符重载函数的对象,称作,或者称作
问题二:那么使用函数对象有什么好处呢?
template<typename T>
bool compare(T a, T b)
{
return a > b;
}
int main()
{
cout << compare(10, 20) << endl;
cout << compare('b','y') << endl;
return 0;
}
我里我们实现了 但是它不够灵活,我们有时想比较小于,每次改动符号有些麻烦,C语言中的函数指针刚好可以很好解决这个问题。
使用C语言中函数指针解决:
//使用C的函数指针解决
template<typename T>
bool mygreater(T a, T b)
{
return a > b;
}
template<typename T>
bool myless(T a, T b)
{
return a < b;
}
//compare是C++的库函数模板
template<typename T, typename Compare>
bool compare(T a, T b, Compare comp)
{
return comp(a, b);
}
int main()
{
cout << compare(10, 20,mygreater<int>) << endl;
cout << compare(10, 20,myless<int>) << endl;
return 0;
}
这时,就可以很好的解决这个问题了,我们传入不同的函数指针来解决,想比较大就传入mygreater,想比较小就传入myless,通过函数指针间接调用函数; 但是这里,我们通过函数指针虽然解决了问题,但。因此,C++有一个专门的函数对象来解决这个问题。
使用C++中函数对象解决:
好处:
通过函数对象调用()运算符重载,可以,比通过函数指针调用函数(不能内联调用)效率高。
因为函数对象是用类生成的,所以可以添加相关的成员变量用来记录函数对象使用时更多的信息。
//C++函数对象实现
template<typename T>
class mygreater
{
public:
bool operator()(T a, T b)//二元函数对象
{
return a > b;
}
};
template<typename T>
class myless
{
public:
bool operator()(T a, T b)//二元函数对象
{
return a < b;
}
};
//compare是C++的库函数模板
template<typename T, typename Compare>
bool compare(T a, T b, Compare comp)
{
return comp(a, b);//编译过程知道调用对象的函数operator()(a, b);
}
int main()
{
cout << compare(10, 20,mygreater<int>()) << endl;
cout << compare(10, 20,myless<int>()) << endl;
return 0;
}
执行成功:函数对象相比于函数指针。
二、使用实例
实例1:优先级队列
我们的优先级队列,底层依赖vector容器,底层默认为一个大根堆。
int main()
{
priority_queue<int> que;//底层vector
for (int i=0; i<10; ++i)//大根堆
{
que.push(rand() % 100);
}
while (!que.empty())
{
cout << que.top() << " ";
que.pop();
}
cout << endl;
return 0;
}
打印一下:堆顶元素最大
如果我们如何做呢? 只是库中的实现:
template<class _Ty,
class _Container = vector<_Ty>,
class _Pr = less<typename _Container::value_type> >
我们将less改为greater即可变为小根堆即可。
using MinHeap = priority_queue<int, vector<int>, greater<int>>;
实例2:set
set底层为红黑树,默认底层从小到大进行输出。底层为:
template<class _Kty,
class _Pr = less<_Kty>,
class _Alloc = allocator<_Kty> >
set<int, greater<int>> set;
for (int i=0; i<10; ++i)
{
set.insert(rand() % 100);
}
for (int v : set)
{
cout << v << " ";
}
cout << endl;
此时:就是从大到小排序。