函数对象:
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待。
这是通过重载类的operator()来实现的。
“在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以使用函数对象或者函数来作为自定的回调行为;
对应的代码如下:
#include<iostream>
using namespace std;
#include "string"
#include <vector>
#include <list>
#include "set"
#include <algorithm>
#include "functional"
//函数对象 类重载了()
template<typename T>
class ShowElemt
{
public:
ShowElemt()
{
n = 0;
}
void operator()(T &t)
{
n++;
cout << t << " ";
}
void printN()
{
cout << " n: " << n << endl;
}
protected:
private:
int n;
};
//函数模板 ==函数
template<typename T>
void FuncShowElemt(T& t)
{
cout << t << endl;
}
//普通函数
void FuncShowElemt2(int& t)
{
cout << t << " ";
}
//函数对象定义: 函数对象和普通函数的异同
//
void main01()
{
int a = 10;
ShowElemt<int> showElemt;
showElemt(a); //输出10,函数对象()的执行很像一个函数,仿函数
FuncShowElemt<int>(a); //输出10
FuncShowElemt2(a); //输出10
}
/**
函数对象是属于类对象,能突破函数的概念,能保持调用状态信息
函数对象的好处
for_each算法中,函数对象做函数参数
for_each算法中,函数对象当返回值
*/
void main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
for_each(v1.begin(),v1.end(),ShowElemt<int>()); // 输出1,3,5 //通过匿名函数对象
cout << endl;
for_each(v1.begin(),v1.end(),FuncShowElemt2); //输出1,3,5 //通过回调函数
//for_each算法的函数对象传递的是元素值的传递,而不是引用传递
ShowElemt<int> show1;
for_each(v1.begin(),v1.end(),show1); //输出1,3,5
show1.printN(); //输出0
cout<<"通过for_each算法的返回值看调用的次数"<<endl;
show1 = for_each(v1.begin(), v1.end(), show1); //输出 1,3,5
show1.printN(); //输出3
//结论要点:分清楚stL算法返回的值是迭代器还是谓词(函数对象)是STL算法的入门基础
}