程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 小議c++之回調

小議c++之回調

編輯: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() www.2cto.com
 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 功能挺強大的,用它來實現回調和委托還是很方便的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved