小议c++之回调

   最近在做一个军团系统的资料片开发,因为策划提出了很多遍历某一军团当前所有在线玩家的操作(例如发公告、拉人、给奖励),所以就想到了用回调。
   脱离实际项目代码,先看一下示例实现:
  1 /**
  2  *\author peakflys 
  3  *\brief C方式实现的C++回调
  4  
*/
  5 #include <iostream>
  6 #include <vector>
  7 
  8 #define COUNTARRAY(a) sizeof(a)/sizeof(a[0])
  9 
 10 class User
 11 {
 12     public:
 13         User(std::string _name,bool _online) : name(_name),online(_online)
 14         {
 15         }
 16         const std::string& getName() const
 17         {
 18             return this->name;
 19         }
 20         bool checkOnLine()
 21         {
 22             return online;
 23         }
 24     private:
 25         std::string name;
 26         bool online;
 27 };
 28 
 29 class Test;
 30 typedef void(Test::*pFun)(const User&);//成员函数
 31 
 32 class Test
 33 {
 34     public:
 35         Test(const std::vector<User>& _userList) : userList(_userList)
 36         {
 37         }
 38 
 39         void print(const User& user);
 40 

 41         void execEvery(pFun fun);
 42 
 43     private:
 44         std::vector<User> userList;
 45 };
 46 
 47 void Test::print(const User& user)
 48 {
 49     std::cout<<user.getName()<<" ";
 50 }
 51 
 52 void Test::execEvery(pFun fun)
 53 {
 54     for(std::vector<User>::iterator it=userList.begin();it!=userList.end();++it)
 55     {
 56         if((*it).checkOnLine())
 57             (this->*fun)(*it); //注意格式
 58     }
 59     std::cout<<std::endl;
 60 }
 61 
 62 int main()
 63 {
 64     User um[] = {User("张三",true),User("李四",false),User("王二",true),User("麻子",true)};
 65     std::vector<User> vu(um,um+COUNTARRAY(um));
 66     Test t(vu);
 67     t.execEvery(&Test::print);
 68     return 0;
 69 }
写完之后编译、运行,一切okay,不过后来再看相应代码时,越看越不顺眼,尤其是类似于示例中的第57行:(this->*fun)(*it);  ,感觉使用很暴力,完全没有OO的优雅感,突然间想到了c++ TR1草案中的function和bind函数(c++11已经将其转正了)。
   于是重新实现回调功能,示例代码如下:
  1 /**
  2  *\author peakflys 
  3  *\brief C++方式实现的C++回调
  4  
*/
  5 #include <iostream>
  6 #include <vector>
  7 #include <tr1/functional>
  8 
  9 #define COUNTARRAY(a) sizeof(a)/sizeof(a[0])
 10 
 11 class User
 12 {
 13     public:
 14         User(std::string _name,bool _online) : name(_name),online(_online)
 15         {
 16         }
 17         const std::string& getName() const
 18         {
 19             return this->name;
 20         }
 21         bool checkOnLine()
 22         {
 23             return online;
 24         }
 25     private:
 26         std::string name;
 27         bool online;
 28 };
 29 
 30 class Test
 31 {
 32     public:
 33         Test(const std::vector<User>& _userList) : userList(_userList)
 34         {
 35         }
 36 
 37         void static print(const User& user);
 38 
 39         void execEvery(std::tr1::function<void (const User&)> func);
 40     private:
 41         std::vector<User> userList;
 42 };
 43 
 44 void Test::print(const User& user)
 45 {
 46     std::cout<<user.getName()<<" ";
 47 }
 48 
 49 void Test::execEvery(std::tr1::function<void (const User&)> func)
 50 {
 51     for(std::vector<User>::iterator it=userList.begin();it!=userList.end();++it)
 52     {
 53         if((*it).checkOnLine())
 54             func(*it); //注意格式
 55     }
 56     std::cout<<std::endl;
 57 }
 58 
 59 int main()
 60 {
 61     User um[] = {User("张三",true),User("李四",false),User("王二",true),User("麻子",true)};
 62     std::vector<User> vu(um,um+COUNTARRAY(um));
 63     Test t(vu);
 64     t.execEvery(std::tr1::bind(Test::print,std::tr1::placeholders::_1));
 65     return 0;
 66 }
本文使用的编译环境是 gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46),c++11已经把命名空间std::tr1下的函数赚到了std下。
这样实现,看起来就好很多了,可读性也高了不少。新标准扩展的function和bind 功能挺强大的,用它来实现回调和委托还是很方便的。

posted on 2012-08-31 21:38 peakflys 阅读(2858) 评论(1)  编辑 收藏 引用 所属分类: C++

评论

# re: 小议c++之回调[未登录] 2012-09-03 14:10 陈梓瀚(vczh)

只要你用的是VC++2008或者以上,就可以有std::tr1::function或者std::function,请不要浪费时间考虑别的方法,除非你的callback是一个包含多个method的类似template method pattern一样的callback接口  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年1月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

公告

人不淡定的时候,就爱表现出来,敲代码如此,偶尔的灵感亦如此……

常用链接

留言簿(4)

随笔分类

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜