仿函数与回调函数
在之前聊了小括号重载和回调函数,现在来聊聊仿函数,以及它和回调函数的关系。
仿函数是对象使用行为看上去像个函数。
函数的使用是这个样的
Function(param1,param2,...)
而对象的使用是这个样的
Object.memberfunction(param1,param2...)
而仿函数对象的使用是这个样的
Object(param1,param2,...)
这样我们可以看出,从外表上看,仿函数对象和函数是一个东西。呵呵,当然他们是不同的。他们一样不过是在使用的外形上一样罢了。
#include <iostream> using namespace std; #include <string> ////////////////////////////////////////////////////////////////////////// enum Conversion_Ch { UPPER = 0, //大写 LOWER, //小写 }; /* ** 仿函数 */ class CFunctor { public: CFunctor( int conversion ); public: /* ** 重载小括号 ** 实现仿函数的核心 */ char operator() ( char ch ) const; private: int m_nConversion; }; CFunctor::CFunctor( int conversion ) : m_nConversion(conversion) { } char CFunctor::operator() ( char ch ) const { switch ( m_nConversion ) { case UPPER: { return ch & 0x5F; } break; case LOWER: { return ch | 0x20; } break; default: break; } return ch; } ////////////////////////////////////////////////////////////////////////// /* ** 转换函数 ** 利用仿函数实现 */ void ConversionFun( const string & str, const CFunctor & functor ) { for ( int i = 0; i < (int)str.length(); ++i ) { char ch = str[i]; cout << functor( ch ); } return; } ////////////////////////////////////////////////////////////////////////// typedef char (*pFun)( char ch ); char UpperFun( char ch ) { return ch & 0x5F; } char LowerFun( char ch ) { return ch | 0x20; } /* ** 转换函数 ** 利用回调函数实现 */ void ConversionFun( const string & str, const pFun functor ) { /* ** 注意实现代码,跟仿函数的一摸一样 ** 仿函数名称也是来源于此 */ for ( int i = 0; i < (int)str.length(); ++i ) { char ch = str[i]; cout << functor( ch ); } return; } ////////////////////////////////////////////////////////////////////////// int main() { string str1 = "AbCdEfGhIjKlMn"; // 利用仿函数,将str1转换为大写字符串 ConversionFun( str1, CFunctor(UPPER) ); cout<< endl; // 利用仿函数,将str1转换为小写字符串 ConversionFun( str1, CFunctor(LOWER) ); cout<< endl; // 利用回调函数,将str1转换为大写字符串 ConversionFun( str1, UpperFun ); cout<< endl; // 利用回调函数,将str1转换为小写字符串 ConversionFun( str1, LowerFun ); cout<< endl; return 0; }
参考资料
1.http://www.cppblog.com/walkspeed/archive/2008/11/21/4510.html
2.http://www.cnitblog.com/jackrain/archive/2005/10/10/3207.html(蛮有用的一个方法)
3.http://hi.baidu.com/laodun/blog/item/ffcc8f82e2108694f603a696.html
4.http://hi.baidu.com/ruo0ruo/blog/item/19525bca54d4f314bf09e653.html