ktv在那些网站做宣传效果好,云南建设学院的网站,廊坊市建设银行网站,少儿培训http://blog.csdn.net/jnu_simba/article/details/9500219 一、函数对象 1、函数对象#xff08;function object#xff09;也称为仿函数#xff08;functor#xff09; 2、一个行为类似函数的对象#xff0c;它可以没有参数#xff0c;也可以带有若干参数。 3、任何重载…http://blog.csdn.net/jnu_simba/article/details/9500219 一、函数对象 1、函数对象function object也称为仿函数functor 2、一个行为类似函数的对象它可以没有参数也可以带有若干参数。 3、任何重载了调用运算符operator()的类的对象都满足函数对象的特征 4、函数对象可以把它称之为smart function。 5、STL中也定义了一些标准的函数对象如果以功能划分可以分为算术运算、关系运算、逻辑运算三大类。为了调用这些标准函数对象需要包含头文件functional。 二、自定义函数对象 C Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include iostream using namespace std; class CFunObj { public: void operator()() { cout hello,function object! endl; } }; int main() { CFunObj fo; fo(); CFunObj()(); return 0; } 注意CFunObj()(); 表示先构造一个匿名对象再调用operator(); 三、函数对象与容器 在这边举map 容器的例子大家都知道map 在插入元素的时候会自动排序默认是根据key 从小到大排序看map 的定义 C Code 1 2 3 4 5 6 7 8 9 10 // TEMPLATE CLASS map template class _Kty, class _Ty, class _Pr less_Kty, class _Alloc allocatorpairconst _Kty, _Ty class map : public _Tree_Tmap_traits_Kty, _Ty, _Pr, _Alloc, false { // ordered red-black tree of {key, mapped} values, unique keys }; 假设现在我们这样使用 map int, string mapTest; 那么默认的第三个参数 _Pr lessint再者map 继承的其中一个类 _Tmap_traits 中有个成员 _Pr comp;// the comparator predicate for keys 跟踪进insert 函数其中有这样一句 if (_DEBUG_LT_PRED(this-comp, _Key(_Where._Mynode()), this-_Kfn(_Val))) 已知 #define _DEBUG_LT_PRED(pred, x, y) pred(x, y) 很明显地comp 在这里当作函数对象使用传入两个参数回头看less 类的 模板实现 C Code 1 2 3 4 5 6 7 8 9 10 11 12 13 // TEMPLATE STRUCT less templateclass _Ty struct less : public binary_function_Ty, _Ty, bool { // functor for operator bool operator()(const _Ty _Left, const _Ty _Right) const { // apply operator to operands return (_Left _Right); } }; 即实现了operator() 函数左操作数小于右操作数时返回为真。 我们也可以在定义的时候传递第三个参数如map int, string, greaterint mapTest; 则插入时按key 值从大到小排序less, greater 都是STL内置的类里面实现了operator() 函数甚至也可以自己实现一个类传递进去如下面例程所示 C Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include map #include string #include iostream using namespace std; struct MyGreater { bool operator()(int left, int right) { return left right; } }; int main(void) { map int, string, /*greaterint */MyGreater mapTest; mapTest.insert(mapint, string::value_type(1, aaaa)); mapTest.insert(mapint, string::value_type(3, cccc)); mapTest.insert(mapint, string::value_type(2, bbbb)); for (map int, string, /*greaterint */MyGreater ::const_iterator it mapTest.begin(); it ! mapTest.end(); it) { cout it-first it-second endl; } return 0; } 输出为 3 cccc 2 bbbb 1 aaaa MyGreater 类并不是以模板实现只是比较key 值为int 类型的大小。 四、函数对象与算法 在STL一些算法中可以传入函数指针实现自定义比较逻辑或者计算同样地这些函数也可以使用函数对象来代替直接看例程再稍 作分析 C Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 #include vector #include string #include iostream #include algorithm using namespace std; void PrintFun(int n) { cout n ; } void Add3(int n) { n 3; } class PrintObj { public: void operator()(int n) { cout n ; } }; class AddObj { public: AddObj(int number) : number_(number) { } void operator()(int n) { n number_; } private: int number_; }; class GreaterObj { public: GreaterObj(int number) : number_(number) { } bool operator()(int n) { return n number_; } private: int number_; }; int main(void) { int a[] {1, 2, 3, 4, 5}; vectorint v(a, a 5); /*for_each(v.begin(), v.end(), PrintFun); coutendl;*/ for_each(v.begin(), v.end(), PrintObj()); cout endl; /*for_each(v.begin(), v.end(), Add3); for_each(v.begin(), v.end(), PrintFun); coutendl;*/ for_each(v.begin(), v.end(), AddObj(5)); for_each(v.begin(), v.end(), PrintFun); cout endl; cout count_if(a, a 5, GreaterObj(3)) endl; //计算大于3的元素个数 return 0; } 输出为 1 2 3 4 5 6 7 8 9 10 2 回顾for_each 的源码其中有这样一句 _Func(*_ChkFirst); 也就是将遍历得到的元素当作参数传入函数。 上面程序使用了函数对象实际上可以这样理解 PrintObj()(*_ChkFirst); 即 PrintObj() 是一个匿名的函数对象传入参 数调用了operator() 函数进行打印输出。使用函数对象的好处是比较灵活比如直接使用函数Add3那么只能将元素加3而 使用函数对象Addobj(x), 想让元素加上多少就传递给Addobj类构造一个对象即可因为它可以保存一种状态类成员。 count_if 中的 GreaterObj(3) 就类似了将遍历的元素当作参数传递给operator(), 即若元素比3大则返回为真。 五、STL内置的函数对象类 参考 C primer 第四版 Effective C 3rd C编程规范