函数对象

总结下函数对象

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

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));
可以发现,由于函数对象的使用,算法库中接受谓词的算法一下子就灵活了起来。

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


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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值