函数只是表达一个运算过程,像沙漏,流过后不留下任何痕迹,如果遇到用一个函数统计容器所有Student对象的身高,就必须累加上次累加的结果。这时就必须用到函数对象。
函数对象:就是定义了函数调用操作符,即operator()的普通类的对象。
例如,可以定义一个函数对象类来实现比较两个数的大小
代码如下:
// 3.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <vector> using namespace std; //模板函数对象的定义 template <typename T> class mymax { public: T operator ()( T a, T b) { return a > b ? a : b; } }; //利用函数对象定义函数模板 template <typename T> T compare( T a, T b, mymax<T>& op) { return op(a, b); } int _tmain(int argc, _TCHAR* argv[]) { //定义一个int类型的函数对象 mymax<int> intmax; //直接对函数对象使用 int nMax1 = intmax(2, 3); //作为参数传递给其他函数 int nMax2 = compare(1, 0, intmax); return 0; }
// 3.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <vector> #include <algorithm> using namespace std; //定义student类 class Student { public: Student() { m_strName = ""; m_nHeight = 0; } public: Student( string strName, int nHeight) : m_strName(strName), m_nHeight(nHeight) { } string GetName() { return m_strName; } int GetHeight() { return m_nHeight; } private: string m_strName; int m_nHeight; }; //定义一个函数对象类 class AverageHeight { public: //构造函数,对类的成员属性初始化 AverageHeight() : m_nCount(0) , m_nTotalHeight(0) { }; //重载函数调用操作符“()” //完成统计功能 void operator () ( Student st ) { m_nTotalHeight += st.GetHeight(); ++m_nCount; } //以下都是借口函数 float GetAverageHeight() { if ( 0 != m_nCount ) { return (float)GetTotal()/GetCount(); } } int GetCount() { return m_nCount; } int GetTotal() { return m_nTotalHeight; } private: int m_nCount; int m_nTotalHeight; }; int _tmain(int argc, _TCHAR* argv[]) { vector<Student> vecStu; Student st1( "zhouzhou", 180 ); Student st2( "xiaoxiao", 162 ); Student st3( "huhu", 176 ); vecStu.push_back(st1); vecStu.push_back(st2); vecStu.push_back(st3); AverageHeight ah; ah = for_each( vecStu.begin(), vecStu.end(), ah); cout<<ah.GetCount()<<"个学生的平均身高是:"<<ah.GetAverageHeight()<<endl; return 0; }
为了减少定义函数对象类工作,STL预定义了许多常用的函数对象:
一、算术操作
这类对象可以用于常见的算术运算,例如,加(plus)、减(minus)、乘(multiplies)、除(divides)、取余(modules)和取负(negate)等
二、比较操作
这类对象可以用于进行数据的比较,例如,等于(equal_to)、不等于(not_equal_to)、大于(greater)、小于(less)、大于等于(greater_equal)、小于等于(less_equal)
三、逻辑操作
这类对象可以用来逻辑运算,例如,逻辑与(logical_and)、逻辑或(logical_or)、逻辑非(logical_not)
例如:
统计容器中大于60的数据个数
int nCount = count_if( vecScore.begin(), vecScore.end(), bind2nd( greater<int>(), 60) );