学习 Boost:bind/Boost::functions closure as delegate in C++
来源:互联网 发布:js checkbox onchange 编辑:程序博客网 时间:2024/06/05 02:41
今天分享一篇比较短的博文. 关于Boost bind/function.
最近读了陈硕的博文 http://blog.csdn.net/solstice/article/details/3066268, 有一些自己的看法, 感觉最后那个麻雀,企鹅的例子没有把bind的妙处表示清楚. 于是自己有了一些思考,分享如下:
1) Boost::function是一些类模板, 实质是函数对象的封装, 也就是把一个回调(函数指针) 封装起来, 使之具有对象的语义, 在对象的生命周期内推迟真正的调用时机.
2) Boost::bind是一个函数对象的工厂, 用来产生需要的函数对象. 从Boost的文档里得知, 其可用于函数,函数对象,成员函数,函数指针等多种回调类型.
3) 这个东西, 个人认为并没有很多东西, 是Boost提供的对委托/回调的一种比较干净优雅的解决方案.
那这个东西到底有什么用? 该何时使用呢? 个人浅见, 欢迎拍砖:
1) 使用Boost::bind的委托对象, 如果封装的是对象的方法, 则在创建的时候就传入了对象实例, 调用的时候不需要对象实例.
2) 封装/定义回调的方法比函数指针要简洁.
3) 不是说这个东西要代替OO, 回调/委托和OO虚函数是不同的技术, 各自有适用的问题域. 如果是对象族有公共的行为或状态, 使用继承和多态是合理的. 如果对象间的协作和调用具有较少的公共行为, 可以使用委托和回调组合对象的行为, 用继承的显得笨重.
来个例子建模上述观点:
有很多小动物, 有企鹅, 可以跑,可以游泳, 有麻雀, 可以跑, 可以飞, 有聪明的猴子,会跑, 会骑车, 还有小马, 擅长跑.
现在来举办一场动物的铁人三项赛, 有跑步, 游泳, 骑自行车三个子项目, 请选择合适的选手, 编程实现比赛.
分析:
1) 动物对象的协作和调用似乎具有较少的公共行为, 跑,游泳, 骑车, 飞, 似乎用虚函数建模不会有明显的收益.
2) 赛事对象的关键是跑步, 游泳, 骑车三个动作, 提取动物的动作(回调), 组装到我们的赛事对象里, 就可以了.
围绕委托来编程, 首先定义这些动作:
// Use closuer allback as interfacestypedef boost::function<void()> FlyCallback;typedef boost::function<void()> RunCallback;typedef boost::function<void()> SwimCallback;typedef boost::function<void()> RideCallback;定义我们的参赛选手:
// Pengin can run, and swimclass Penguin{ public: void run() {std::cout<<"Penguin running"<<std::endl;} void swim(){std::cout<<"Penguin swimming"<<std::endl;}};// Sparrow can fly, can runclass Sparrow{ public: void fly() {std::cout<<"Sparrow flying"<<std::endl;} void run() {std::cout<<"Sparrow running"<<std::endl;}};//Horse runs goodclass Horse{ public: void run() {std::cout<<"Horse running"<<std::endl;}};//Monkey is clever, can ride a bicycle and runclass CleverMonkey{public: void ride() {std::cout<<"Monkey riding"<<std::endl;} void run() {std::cout<<"Monkey running"<<std::endl;}};定义我们的赛事, 有跑, 游泳, 骑车三个子回调组成:
// Anmial triathlon's matchclass Triathlon{ public: Triathlon(SwimCallback swimCb, RunCallback runCb, RideCallback rideCb) : swimCb_(swimCb), runCb_(runCb), rideCb_(rideCb) { } void Start() { std::cout<<"The match start! first is running event."<<std::endl; runCb_(); std::cout<<"Running completed! now is swimming event."<<std::endl; swimCb_(); std::cout<<"Swimming completed! now is riding event."<<std::endl; rideCb_(); std::cout<<"Riding completed! you've got a good score."<<std::endl; } private: RunCallback runCb_; SwimCallback swimCb_; RideCallback rideCb_;};最后,选拔我们的队员, 参加赛事(使用Boost::bind将动物的动作通过回调组合到赛事:
int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); Sparrow s; Penguin p; Horse h; CleverMonkey m; //Now, we have a trathlon match for animals. //Looks only penguin can swim, let he take swimming //The horse should run better than sparrow and monkey and penguin, let he take running. //The monkey is the only candidate for smart enough for riding a bicycle, it's his job. Triathlon triathlon(boost::bind(&Penguin::swim, &p), boost::bind(&Horse::run, &h), boost::bind(&CleverMonkey::ride, &m)); triathlon.Start(); return a.exec();}完毕. 用起来似乎比使用面向对象虚函数建模要顺手不少. 总结一下Boost::bind/Boost::function会有用武之地的地方:
1) 方便用回调委托建模的地方 ( 似乎设计模式的行为型模式(策略, 模板方法) 可以考虑用这个代替了)
2) Command模式.
不复杂, 就是说C++的用户们, 用回调委托的话, 多多用Boost::bind, Boost::function吧.
- 学习 Boost:bind/Boost::functions closure as delegate in C++
- 【boost学习】之boost::bind
- Boost学习笔记-bind
- boost::bind 学习
- boost学习之bind
- boost 线程学习bind
- Boost::bind学习
- [C++] boost::function boost::bind 与 回调
- boost::bind And Objective-C
- Closure and anonymous functions in Objective-C
- Boost学习笔记之bind
- boost::bind实现原理学习
- boost::bind\boost::function
- 【Boost】boost::bind介绍
- boost::bind/boost::function
- boost.bind
- boost::bind
- boost::bind
- struts Action只执行一次问题
- Android -- SparseArray<E>详解
- eXtremeDB高可用版(HA)嵌入式数据库
- Spring与Hibernate集成:编程式事务和声明式事务的区别
- drupal path alias 和drupal path auto module 的逻辑简单总结
- 学习 Boost:bind/Boost::functions closure as delegate in C++
- 深度辨析 Java 中的 finally 语句块
- qeePHP学习 使用websetup生成
- oracle count()查询速度优化
- android安全学习笔记(三)
- redis安装与测试
- qeePHP学习 qeePHP基本设置
- PHP用户的常用的MySQL管理工具介绍
- Git使用基础篇