1、函数对象
函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性。大多数STL算法可以用一个函数对象作为参数。所谓“函数对象”其实就是一个行为类似函数的对象,它可以不需要参数,也可以带有若干参数,其功能是获取一个值,或者改变操作的状态。
在c++程序设计中,任何普通的函数和任何重载了调用运算符operator()的类的对象都满足函数对象的特征,因此都可以作为函数对象传递给算法作为参数使用。
以数值算法accumulate()为例子,介绍函数对象的设计及应用过程。
数值算法accumulate()的调用格式包括两种:第一种调用格式是以"+"运算符作为运算规则,第二种算法允许用户铜鼓哦传递给算法相应的函数对象来指定计算规则。
一般来说,用户设计的普通函数就是一种最简单的函数对象,
例子1:利用普通函数来定义函数对象
#include<iostream>
#include<numeric> //包含数值算法头文件
using namespace std;
int mutl(int x, int y)
{ return x + y; }//定义一个普通函数
int main() {
int A[] = {1,2,3,4,5};
const int N = sizeof(A) / sizeof(int);
cout << "The result by multipling all elements in A is" << accumulate(A, A + N, 1, mutl);
getchar();
cout<<endl;//将普通函数mutl传递给通用算法
}
除了普通函数,另一类函数对象可以是类的对象,并且在定义中重载函数调用运算符。
例子2:改写上面的程序
#include<iostream>
#include<numeric> //包含数值算法头文件
using namespace std;
class multclass //定义multclass类
{ public:
int operator()( int x, int y )const{return x*y; }//重载操作符operator()
};
int main()
{
int A[] = { 1, 2, 3, 4, 5 };
const int N = sizeof(A) / sizeof(int);
cout << "The result by multipling all elements in A is" << accumulate(A, A + N, 1, multclass());//将类multclass传递给通用算法
getchar();
cout << endl;//将普通函数mutl传递给通用算法
}
分析:通过在类multclass中重载运算符operator(),就定义了一种可以作为函数参数的对象,同样可以像使用普通函数mutl一样来使用该对象。但是这里传递给算法accumulate的对象是通过multclass类的默认构造函数multclass()获得的,它可以由编译器自动提供。使用类的形式定义的函数对象能够比普通函数携带更多的额外信息。
除了上面之外,STL中也定义了一些标准的函数对象,如果以功能划分,可以分为算数运算、关系运算、逻辑运算三大类。为了调用这些标准函数对象,需要包含头文件<functional>。标准函数对象是内连函数。
2、函数适配器
与前面介绍过的迭代器适配器的作用类似,函数适配器也可以帮助创建种类更多的函数对象。与直接铜鼓哦结构或类定义来创建新的函数对象相比,使用函数适配器是一种更加容易的方式。