在程序设计中函数一般被当做一段逻辑段, 它接收参数, 并返回逻辑运算的结果。 在
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 fun;
fun = test; fun();
(只是探讨c++ fucntor 模板技术的实现原理, 只实现接收一个参数的fucntor)
1. 首先是模板原型:
template class functor;
2. 接口模板类:
template class functor_impl;
然后进行特化:
template
class functor_impl
{
public:
virtual ~functor_impl() {}
virtual ReturnType operator()(Arg1_Type a) =0;
};
3. 接口模板类的实现。
template class functor_handler;
template
class functor_handler
: public functor_impl
{
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
class functor
{
public:
typedef R ReturnType;
typedef X Arg1_Type;
typedef functor ProtypeFun;
functor():ptr_f(NULL)
{}
~functor(){delete ptr_f;}
template
ProtypeFun& operator= (Fun f)
{
if(ptr_f) delete ptr_f;
ptr_f = new functor_handler(f);
return *this;
}
ReturnType operator()(Arg1_Type a)
{
return (*ptr_f)(a);
}
private:
functor_impl* ptr_f;
};
阅读(5634) | 评论(1) | 转发(1) |