利用C++函数对象实现解耦
时间:2010-09-05 来源:gogozhaoxinfeng
在程序设计中函数一般被当做一段逻辑段, 它接收参数, 并返回逻辑运算的结果。 在C/C++ 程序中, 函数不只能接收参数, 还能作为参数作为其他函数的参数, 我们已经非常熟悉这种用法了, 那就是回调函数。 使用回调函数可以大大实现软件设计的解耦, 其主要应用如下:
1. 处理事件; 如GUI中, 点击鼠标, 将会触发click事件, 注册此事件的回调函数将会被执行。
2. 异步模式; 如网络程序中, 非常经典的proactor模式,就大量的使用回调函数。 如Boost ASIO中异步发送数据 sock.async_write(boost::buffer(data,len), write_handle); 其中write_handle为 回调函数。
3. 实现特定的算法; 最典型的事 C++ STL algorithm, 如for_each(iter_begin, iter_end, deal_each); 其中deal_each 为函数指针或仿函数。
4. 一些设计模式, 如策略模式, Gof中的策略通常用虚函数即多态来实现, 又是利用回调函数也可以, 而且更灵活, 如logic 类需要调用平台的借口, 平台不同参数不同, 那么可以像logic类注册一个回调函数如 string (func*)(int uid); 这样, 当logic类需要调用平台时只需要先调用一下回调函数产生参数即可, 而logic 类不需要知道这些参数到底由那个类负责产生。
5. 其他...... , 如atexit, sig_handle, 等用回调函数来捕获异常。
在c++ 中函数有如下几类: 1. C 类型全局函数 2. C++类成员函数 3. C++仿函数
在C++库中, Boost::function库非常强大, CSDN有网友讨论了利用Boost::function 代替虚函数, 很有意思。 加上Boost提供的bind和lamda, 非常易用, 在利用boost asio开发服务器程序时, 我们大量使用了boost function, 最近研究了一下c++ functor的实现方式, 特此记录一下心得体会, 参考了Andrei Alexandrescu 的 Loki 库。 最终实现的functor 使用方法如下: void test(int a){} struct test2{ void operator()(int a){} };
functor<void (int)> fun; fun = test; fun(); fun = test2; fun();
(只是探讨c++ fucntor 模板技术的实现原理, 只实现接收一个参数的fucntor)
1. 首先是模板原型: template<typename T> class functor;
2. 接口模板类: template <typename FuncType> class functor_impl; 然后进行特化: 接收一个参数的函数对象接口定义 template <typename ReturnType, typename Arg1_Type> class functor_impl<ReturnType (Arg1_Type)> { public: virtual ~functor_impl() {} virtual ReturnType operator()(Arg1_Type a) =0; };
3. 接口模板类的实现。 template<typename FuncType, typename Fun> class functor_handler;
template<typename ReturnType, typename Arg1_Type, typename Fun> class functor_handler<ReturnType (Arg1_Type), Fun> : public functor_impl<ReturnType (Arg1_Type)> { public: functor_handler() {} functor_handler(const Fun& f):m_f(f) {}
ReturnType operator()(Arg1_Type a) { return m_f(a); } void operator=(Fun f) { m_f = f; } private: Fun m_f; };
4. fuctor 的实现。
template <typename R, typename X> class functor<R (X)> { public: typedef R ReturnType; typedef X Arg1_Type;
typedef functor<ReturnType (Arg1_Type)> ProtypeFun; functor():ptr_f(NULL) {} ~functor(){delete ptr_f;} template <class Fun> ProtypeFun& operator= (Fun f) { if(ptr_f) delete ptr_f; ptr_f = new functor_handler<ReturnType (Arg1_Type), Fun>(f); return *this; } ReturnType operator()(Arg1_Type a) { return (*ptr_f)(a); } private: functor_impl<ReturnType (Arg1_Type)>* ptr_f; };
1. 处理事件; 如GUI中, 点击鼠标, 将会触发click事件, 注册此事件的回调函数将会被执行。
2. 异步模式; 如网络程序中, 非常经典的proactor模式,就大量的使用回调函数。 如Boost ASIO中异步发送数据 sock.async_write(boost::buffer(data,len), write_handle); 其中write_handle为 回调函数。
3. 实现特定的算法; 最典型的事 C++ STL algorithm, 如for_each(iter_begin, iter_end, deal_each); 其中deal_each 为函数指针或仿函数。
4. 一些设计模式, 如策略模式, Gof中的策略通常用虚函数即多态来实现, 又是利用回调函数也可以, 而且更灵活, 如logic 类需要调用平台的借口, 平台不同参数不同, 那么可以像logic类注册一个回调函数如 string (func*)(int uid); 这样, 当logic类需要调用平台时只需要先调用一下回调函数产生参数即可, 而logic 类不需要知道这些参数到底由那个类负责产生。
5. 其他...... , 如atexit, sig_handle, 等用回调函数来捕获异常。
在c++ 中函数有如下几类: 1. C 类型全局函数 2. C++类成员函数 3. C++仿函数
在C++库中, Boost::function库非常强大, CSDN有网友讨论了利用Boost::function 代替虚函数, 很有意思。 加上Boost提供的bind和lamda, 非常易用, 在利用boost asio开发服务器程序时, 我们大量使用了boost function, 最近研究了一下c++ functor的实现方式, 特此记录一下心得体会, 参考了Andrei Alexandrescu 的 Loki 库。 最终实现的functor 使用方法如下: void test(int a){} struct test2{ void operator()(int a){} };
functor<void (int)> fun; fun = test; fun(); fun = test2; fun();
(只是探讨c++ fucntor 模板技术的实现原理, 只实现接收一个参数的fucntor)
1. 首先是模板原型: template<typename T> class functor;
2. 接口模板类: template <typename FuncType> class functor_impl; 然后进行特化: 接收一个参数的函数对象接口定义 template <typename ReturnType, typename Arg1_Type> class functor_impl<ReturnType (Arg1_Type)> { public: virtual ~functor_impl() {} virtual ReturnType operator()(Arg1_Type a) =0; };
3. 接口模板类的实现。 template<typename FuncType, typename Fun> class functor_handler;
template<typename ReturnType, typename Arg1_Type, typename Fun> class functor_handler<ReturnType (Arg1_Type), Fun> : public functor_impl<ReturnType (Arg1_Type)> { public: functor_handler() {} functor_handler(const Fun& f):m_f(f) {}
ReturnType operator()(Arg1_Type a) { return m_f(a); } void operator=(Fun f) { m_f = f; } private: Fun m_f; };
4. fuctor 的实现。
template <typename R, typename X> class functor<R (X)> { public: typedef R ReturnType; typedef X Arg1_Type;
typedef functor<ReturnType (Arg1_Type)> ProtypeFun; functor():ptr_f(NULL) {} ~functor(){delete ptr_f;} template <class Fun> ProtypeFun& operator= (Fun f) { if(ptr_f) delete ptr_f; ptr_f = new functor_handler<ReturnType (Arg1_Type), Fun>(f); return *this; } ReturnType operator()(Arg1_Type a) { return (*ptr_f)(a); } private: functor_impl<ReturnType (Arg1_Type)>* ptr_f; };
相关阅读 更多 +