zoukankan      html  css  js  c++  java
  • 函数对象

    1、什么是函数对象?

    若一个类重载了()运算符,则该类的对象就称为函数对象。函数对象是个对象,但是用起来看上去象函数调用,实际上也执行了函数调用。

    2、举栗子

    class CMyAverage {
    public:
    	double operator()( int a1, int a2, int a3 ){//重载 () 运算符
    		return (double)(a1 + a2+a3) / 3;
    	}
    };
    void main(){
    	CMyAverage average;		//函数对象
    	cout << average(3,2,3); // average.operator()(3,2,3) 用起来看上去象函数调用 输出 2.66667
    }
    

    3、函数对象的应用

    STL里有以下模板:

    template<class InIt, class T, class Pred>
    T accumulate(InIt first, InIt last, T val, Pred pr);
    
    • pr 就是个函数对象。对[first,last)中的每个迭代器 I,执行 val = pr(val,* I) ,返回最终的val。
    • Pr也可以是个函数。
    //Dev C++ 中的 Accumulate 源代码1:
    template<typename _InputIterator, typename _Tp>
    _Tp accumulate(_InputIterator __first, _InputIterator__last,_Tp __init)
    {
    	for ( ; __first != __last; ++__first)
    		__init = __init + *__first;
    	return __init;
    }
    
    //Dev C++ 中的 Accumulate 源代码2:
    template<typename _InputIterator, typename _Tp,
    typename _BinaryOperation>
    _Tp accumulate(_InputIterator __first, _InputIterator __last,_Tp __init,_BinaryOperation __binary_op)
    {
    	for ( ; __first != __last; ++__first)
    		__init = __binary_op(__init, *__first);
    	return __init;
    }
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <numeric>
    #include <functional>
    using namespace std;
    
    int sumSquares( int total, int value)
    {
    	return total + value * value;
    }
    template <class T>
    void PrintInterval(T first, T last)
    { //输出区间[first,last)中的元素
    	for( ; first != last; ++ first)
    		cout << * first << " ";
    	cout << endl;
    }
    
    template<class T>
    class SumPowers
    {
    private:
    	int power;
    public:
    	SumPowers(int p):power(p) { }
    	const T operator() ( const T & total,const T & value)
    	{ //计算 value的power次方,加到total上
    		T v = value;
    		for( int i = 0;i < power - 1; ++ i)
    			v = v * value;
    		return total + v;
    	}
    };
    
    int main()
    {
    	const int SIZE = 10;
    	int a1[] = { 1,2,3,4,5,6,7,8,9,10 };
    	vector<int> v(a1,a1+SIZE);
    	cout << "1) "; PrintInterval(v.begin(),v.end());
    	int result = accumulate(v.begin(),v.end(),0,SumSquares);
    	cout << "2) 平方和:" << result << endl;
    	result =accumulate(v.begin(),v.end(),0,SumPowers<int>(3));
    	cout << "3) 立方和:" << result << endl;
    	result =accumulate(v.begin(),v.end(),0,SumPowers<int>(4));
    	cout << "4) 4次方和:" << result;
    	return 0;
    }
    
    int result =accumulate(v.begin(),v.end(),0,SumSquares);
    //实例化出:
    int accumulate(vector<int>::iterator
    first,vector<int>::iterator last,
    int init,int ( * op)( int,int))
    {
    	for ( ; first != last; ++first)
    		init = op(init, *first);
    	return init;
    }
    
    accumulate(v.begin(),v.end(),0,SumPowers<int>(3));
    //实例化出:
    int accumulate(vector<int>::iterator first,
    vector<int>::iterator last,
    int init, SumPowers<int> op)
    {
    	for ( ; first != last; ++first)
    		init = op(init, *first);
    	return init;
    }
    

    4、STL 的< functional> 里还有以下函数对象类模板:

    • equal_to
    • greater
    • less

    这些模板可以用来生成函数对象。

    5、greater 函数对象类模板

    template<class T>
    struct greater : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const {
    return x > y;
    }
    };
    //binary_function定义:
    template<class Arg1, class Arg2, class Result>
    struct binary_function {
    	typedef Arg1 first_argument_type;
    	typedef Arg2 second_argument_type;
    	typedef Result result_type;
    };
    

    6、greater 的应用

    (1)list 有两个sort函数,前面例子中看到的是不带参数的sort函数,它将list中的元素按 < 规定的比较方法 升序排列。
    (2)list还有另一个sort函数:可以用 op来比较大小,即 op(x,y) 为true则认为x应该排在前面.
    template <class T2>
    void sort(T2 op);
    
    #include <list>
    #include <iostream>
    #include <iterator>
    using namespace std;
    class MyLess {
    public:
    	bool operator()( const int & c1, const int & c2 )
    	{
    		return (c1 % 10) < (c2 % 10);
    	}
    };
    
    int main()
    {
    	const int SIZE = 5;
    	int a[SIZE] = {5,21,14,2,3};
    	list<int> lst(a,a+SIZE);
    	lst.sort(MyLess());
    	ostream_iterator<int> output(cout,",");
    	copy( lst.begin(),lst.end(),output); 
    	cout << endl;
    	lst.sort(greater<int>()); //greater<int>()是个对象
    	//本句进行降序排序
    	copy( lst.begin(),lst.end(),output); 
    	cout << endl;
    	return 0;
    } 输出:
    21,2,3,14,5,
    21,14,5,3,2,
    

    7、ostream_iterator

    copy类似于

    template <class T1,class T2>
    void Copy(T1 s,T1 e, T2 x)
    {
    	for(; s != e; ++s,++x)
    	*x = *s;
    }
    

    ostream_iterator 如何编写?

    #include <iostream>
    #include <iterator>
    using namespace std;
    class MyLess
    {
    public:
    	bool operator() (int a1,int a2)
    	{
    		if( ( a1 % 10 ) < (a2%10) )
    			return true;
    		else
    			return false;
    	}
    };
    bool MyCompare(int a1,int a2)
    {
    	if( ( a1 % 10 ) < (a2%10) )
    		return false;
    	else
    		return true;
    }
    
    int main()
    {
    	int a[] = {35,7,13,19,12};
    	cout << MyMax(a,5,MyLess()) << endl;
    	cout << MyMax(a,5,MyCompare) << endl;
    	return 0;
    }
    /*输出:
    19
    12
    */
    要求写出MyMax
    
    
    template <class T, class Pred>
    T MyMax( T * p, int n, Pred myless)
    {
    	T tmpmax = p[0];
    	for( int i = 1;i < n;i ++ )
    		if( myless(tmpmax,p[i]))
    			tmpmax = p[i];
    	return tmpmax;
    };
    

    8、引入函数对象后,STL中的“大”,“小”关系

    关联容器和STL中许多算法,都是可以自定义比较器的。在自定义了比较器op的情况下,以下三种说法是等价的:

    • x小于y
    • op(x,y)返回值为true
    • y大于x

    9、比较规则的注意事项

    struct 结构名
    {
    	bool operator()( const T & a1,const T & a2) {
    		//若a1应该在a2前面,则返回true。
    		//否则返回false。
    	}
    };
    
    • 排序规则返回 true,意味着 a1 必须在 a2 前面;返回 false,意味着 a1 并非必须在 a2 前面。
    • 排序规则的写法,不能造成比较 a1,a2 返回 true 比较 a2,a1 也返回 true,否则sort会 runtime error。
    • 比较 a1,a2 返回 false 比较 a2,a1 也返回 false,则没有问题。
  • 相关阅读:
    js闭包
    python切片 []取值操作符
    python with语句
    python鸭子类型(duck type)
    python编码规范
    python @property使用详解
    python __slots__使用详解
    Python面向对象编程
    ifconfig命令详解
    5、Cocos2dx 3.0游戏开发找小三之測试例子简单介绍及小结
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764215.html
Copyright © 2011-2022 走看看