在《C++ STL基础及应用》第6章中,讲到函数对象。就是把函数作为对象的程序设计思维。
STL
是通过重载类中的
operator
函数实现函数对象功能的。它不但可以对容器中的数据进行各种各样的操作,而且能维护自己的状态。因此,与标准的
C
库函数相比,函数对象更为通用。
函数对象是重载了operator()的类的一个实例,operator()是函数调用运算符。标准C++库根据operator()参数个数为0个、1个、2个,这三种情况加以划分。
#include <vector>
#include <algorithm>
using namespace std;
class CSum
{
private:
int sum;
public:
CSum(){sum = 0;}
void operator()(int n)
{
sum+=n;
}
int GetSum()
{
return sum;
}
};
void __fastcall TForm1::Button9Click(TObject *Sender)
{
vector <int > v;
for(int i=0;i<=100;i++)
{
v.push_back(i);
}
CSum sobj = for_each(v.begin(),v.end(),CSum());
ShowMessage(sobj.GetSum());
}
对于这段代码,主要理解以下几点:
(1)必须重载operator函数。这是实现函数对象功能最重的环节,不能随便写。
(2)函数对象的调用方式。直接采用构造函数形式调用。本例中的for_each第三个参数CSum,也就是说,对本例而言,STL知道CSum()对应着CSum类中重载的operator函数,具体几个参数呢?由于for_each函数一次只能迭代一个整数类型,因此,STL知道每迭代一次整型数都要执行一次CSum中的operator(int)函数。
(3)CSum sojb用来接收for_each迭代函数对象的最终结果值。
上例中,编制了求整型向量元素和的功能类CSum,如果求浮点向量的元素和,则必须编制新的函数对象功能类。如果应用一元函数,则问题变得非常简单,代码如下:#include <algorithm>
#include <vector>
template <class _in,class _out>
class CSum1:public unary_function<class _in,class _out>
{
public:
_out sum;
CSum1(_out init)//设置基数
{
sum =init;
}
void operator()(_in n)
{
sum+=n;
}
_out GetSum()
{
return sum;
}
};
void __fastcall TForm1::Button10Click(TObject *Sender)
{
vector<float> v;
for(int i=0;i<=100;i++)
{
v.push_back(i);
}
CSum1<float ,float >sobj = for_each(v.begin(),v.end(),CSum1<float,float>(0));//0是构造函数初始值
ShowMessage(sobj.GetSum());
}
//-------------------------------------