函数对象

来源:互联网 发布:tokiofunka动作数据 编辑:程序博客网 时间:2024/05/07 11:05

总结下函数对象

函数对象可以认为是重载了()的对象。现在想想为什么不用函数指针来进行回调而使用函数指针。

for_each(books.begin() , books.end() , showreview);
它将指定的函数用于区间内的每个成员,如果把第三个参数声明为函数指针,那函数指针会指定参数的类型,但由于容器可以包容任意类型,所以预先无法知道应使用哪种参数类型,因此不能把它声明为函数指针。STL使用模板解决这个问题,for_each的原型看上去就像这样:

template<class InputIterator , class Function>Function for_each(InputIterator first , InputIterator last , Function f);
其中f既可以接受函数指针,也可以接受函数对象的重载()的函数。


②另外函数对象比函数指针更为灵活

例如

bool GT6(const string &s){return s.size() >= 6;}using namespace std;int main(){string s1[10] = {"the","quick","yellow","fox","jumps","over","the","slow","red","turtle"};vector<string> svec(s1,s1+10);for(vector<string>::iterator iter = svec.begin();iter != svec.end();++iter)cout<<*iter<<"\t";vector<string>::size_type wc = count_if(svec.begin(),svec.end(),GT6);cout<<wc<<endl;return 0;}

程序的关键是调用count_if函数来对容器做判断,这个函数接受一个谓词函数,这个谓词函数只有一个形参(类型与容器的中元素的类型相同),且返回值为bool。对于容器中的每个元素,利用谓词函数来判断容器的元素是否满足谓词,count_if的返回值为容器中满足谓词函数的个数。

但这个程序有一个小问题,就是由于count_if只能接受一个带一个形参,这个形参还必须是容器的元素的类型的谓词函数,所以“大于6”这个标准是写在代码中的,如果我们想修改判断标准:改成大于5,那么就必须动谓词函数程序了。这样用起来很不方便,我们希望能把这个标准变成一个参数传递进来,这时我们的函数对象就派上用场了。

class GT_cls{public:GT_cls(size_t val = 0):bound(val){}bool operator()(const string &s){return s.size() >=  bound;}private:string::size_type bound;};

我们为这个类提供了一个数据成员,并提供了一个带参数的构造函数!利用这个参数来控制比较的对象。于是我们就可以这样使用:

wc = count_if(svec.begin(),svec.end(),GT_cls(5));
可以发现,由于函数对象的使用,算法库中接受谓词的算法一下子就灵活了起来。

③虽然函数对象更为灵活,但是函数对象是一个类,类的建立、构造、析构 的开销都很大,而函数指针只是一个指针,对该指针寻址一次即可调用!


夹杂自己的理解并且参考了网上的资料,如有错误请指正!



0 0
原创粉丝点击