青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

每天早晨叫醒你的不是鬧鐘,而是夢想

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

跟諸如Object Pascal和Ada等其它一些語言不同,C++語言并沒有內在地提供一種將類的方法作為回調函數使用的方案。在C語言中,這種回調函數被稱作算子(functor),在事件驅動類程序中普遍存在。主要問題基于這樣一個事實:某個類的多個實例各自位于內存的不同位置。這就需要在回調的時候不僅需要一個函數指針,同時也需要一個指針指向某個實例本身(譯者注:否則回調時便無法知道目前正在操作的是哪個對象,C++類的非靜態方法包含一個默認的“參數”:this指針,就是起這種作用的)。所以,針對問題的定義,有一個很直觀的解決方法就是使用模板和編譯時的實例化及特化。

 解決方案

 這里的方案只支持一個模板參數,但如果一些能夠如愿的話,隨著更多的編譯器完全實現C++標準,以后將會支持動態的模板參數,比如“…”形式的模板參數列表(參見《C++ Templates, The Complete Guide》),那時,我們就可以可以實現無需全部預定義的參數集合。(文中所有代碼的注釋為譯者加,下同。)

 template < class Class, typename ReturnType, typename Parameter >
 class SingularCallBack
 {
   public:
//指向類成員函數的指針,用他來實現回調函數。
 typedef ReturnType (Class::*Method)(Parameter);
     //構造函數
     SingularCallBack(Class* _class_instance, Method _method)
     {
        class_instance = _class_instance;
       method        = _method;
     };
 //重載函數調用運算符()
     ReturnType operator()(Parameter parameter)
     {
        return (class_instance->*method)(parameter);
     };
     //與上面的()等價的函數,引入這個函數的原因見下文
     ReturnType execute(Parameter parameter)
     {
        return operator()(parameter);
 };
    private:
     Class*  class_instance;
     Method  method;
 };
 模板的使用

 模板(template)的使用非常方便,模板本身可被實例化為一個對象指針(object pointer)或者一個簡單的類(class)。當作為對象指針使用時,C++有另外一個令人痛苦的限制:operator() 不可以在指針未被解引用的情況下調用,對于這個限制,一個簡便的但卻不怎么優雅的解決方法在一個模板內部增加一個execute方法(method),由這個方法從模板內部來調用operator()。除了這一點不爽之外,實例化SinglarCallBack為一個對象指針將可以使你擁有一個由回調組成的vector,或者任何其他類型的集合,這在事件驅動程序設計中是非常需要的。
 假設以下兩個類已經存在,而且我們想讓methodB作為我們的回調方法,從代碼中我們可以看到當傳遞一個class A類的參數并調用methodB時,methodB會調用A類的output方法,如果你能在stdout上看到"I am class A :D",就說明回調成功了。
 class A
 {
    public:
    void output()
     {
        std::cout << "I am class A :D" << std::endl;
     };
 };
 class B
 {
    public:
     bool methodB(A a)
     {
        a.output();
        return true;
     }
 };
 有兩種方法可以從一個對象指針上調用一個回調方法,較原始的方法是解引用(dereference)一個對象指針并運行回調方法(即:operator()),第二個選擇是運行execute方法。
 //第一種方法:
 A a;
 B b;
 SingularCallBack< B,bool,A >* cb;
 cb = new SingularCallBack< B,bool,A >(&b,&B::methodB);
 if((*cb)(a))
 {
    std::cout << "CallBack Fired Successfully!" << std::endl;
 }
 else
 {
   std::cout << "CallBack Fired Unsuccessfully!" << std::endl;
 }
 //第二種方法:
 A a;
 B b;
 SingularCallBack< B,bool,A >* cb;
 cb = new SingularCallBack< B,bool,A >(&b,&B::methodB);
 if(cb->execute(a))
 {
    std::cout << "CallBack Fired Successfully!" << std::endl;
 }
 else
 {
    std::cout << "CallBack Fired Unsuccessfully!" << std::endl;
 }
 下面的代碼示范了怎樣將一個模板實例化成一個普通的對象并使用之。
 A a;
 B b;
 SingularCallBack< B,bool,A >cb(&b,&B::methodB);
 {
    std::cout << "CallBack Fired Successfully!" << std::endl;
 }
 else
 {
    std::cout << "CallBack Fired Unsuccessfully!" << std::endl;
 }
 更復雜的例子,一個回調模板可以像下面這樣使用:
 class AClass
 {
   public:
      AClass(unsigned int _id): id(_id){};
     ~AClass(){};
      bool AMethod(std::string str)
      {
         std::cout << "AClass[" << id << "]: " << str << std::endl;
         return true;
      };
    private:
     unsigned int id;
 };
 typedef SingularCallBack < AClass, bool, std::string > ACallBack;
 int main()
 {
    std::vector < ACallBack > callback_list;
    AClass a1(1);
    AClass a2(2);
    AClass a3(3);
    callback_list.push_back(ACallBack(&a1, &AClass::AMethod));
    callback_list.push_back(ACallBack(&a2, &AClass::AMethod));
    callback_list.push_back(ACallBack(&a3, &AClass::AMethod));
    for (unsigned int i = 0; i < callback_list.size(); i++)
    {
       callback_list[i]("abc");
    }
 
   for (unsigned int i = 0; i < callback_list.size(); i++)
   {
      callback_list[i].execute("abc");
   }
 
   return true;
}

下面這個例子比上面的又復雜一些,你可以混合從同一個公共基類(base class)上繼承下來的不同的類到一個容器中,于是你就可以調用位于繼承樹的最底層的類的方法(most derived method)。(譯者注,C++的多態機制)
class BaseClass
{
   public:
     virtual ~BaseClass(){};
     virtual bool DerivedMethod(std::string str){ return true; };
};

class AClass : public BaseClass
{
   public:
     AClass(unsigned int _id): id(_id){};
    ~AClass(){};
     bool AMethod(std::string str)
     {
        std::cout << "AClass[" << id << "]: " << str << std::endl;
        return true;
     };

     bool DerivedMethod(std::string str)
     {
        std::cout << "Derived Method AClass[" << id << "]: " << str << std::endl;
        return true;
     };

   private:
    unsigned int id;
};

class BClass : public BaseClass
{
   public:
    BClass(unsigned int _id): id(_id){};
    ~BClass(){};
     bool BMethod(std::string str)
     {
        std::cout << "BClass[" << id << "]: " << str << std::endl;
        return true;
     };

     bool DerivedMethod(std::string str)
     {
        std::cout << "Derived Method BClass[" << id << "]: " << str << std::endl;
        return true;
     };
   private:
    unsigned int id;

};


typedef SingularCallBack < BaseClass, bool, std::string > BaseCallBack;

int main()
{
   std::vector < BaseCallBack > callback_list;

   AClass a(1);
   BClass b(2);

   callback_list.push_back(BaseCallBack(&a, &BaseClass::DerivedMethod));
   callback_list.push_back(BaseCallBack(&b, &BaseClass::DerivedMethod));

   for (unsigned int i = 0; i < callback_list.size(); i++)
   {
      callback_list[i]("abc");
   }

   for (unsigned int i = 0; i < callback_list.size(); i++)
   {
      callback_list[i].execute("abc");
   }

   return true;
}

為簡捷起見,與實例的驗證(instance validation)相關的必要代碼沒有被包含進來,在實際的程序設計中,類實例的傳遞應該基于這樣的結構:使用類似智能指針(smart pointer)的包裝類。STL(標準模板庫)提供了兩個極好的選擇:aotu_ptr以及它的后繼:shared_ptr。Andrei Alexandrescu所著的《Modern C++ Design》一書也提供了一個面向策略設計(policy design oriented)的智能指針類。這三種方案中各有自己的優缺點,最終由用戶自己來決定究竟那一種最適合他們的需要。

posted on 2011-04-14 22:12 沛沛 閱讀(683) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美在线播放| 久热综合在线亚洲精品| 亚洲国产小视频| 美日韩在线观看| 亚洲福利视频一区二区| 男人天堂欧美日韩| 欧美金8天国| 亚洲私人影吧| 性感少妇一区| 亚洲电影在线看| 亚洲久久视频| 国产日韩欧美高清| 亚洲电影免费观看高清完整版在线观看| 久久亚洲国产精品一区二区 | 一区二区三区你懂的| 欧美三级在线| 久久综合狠狠综合久久综合88| 麻豆成人91精品二区三区| 99精品热视频| 欧美一区二区高清| 91久久精品国产91性色tv| 一区二区三区导航| 影音先锋亚洲精品| 亚洲视频一区| 亚洲国产女人aaa毛片在线| a4yy欧美一区二区三区| 黄色精品免费| 一区二区欧美日韩视频| 亚洲第一在线综合在线| 亚洲网站视频| 亚洲人www| 久久国产天堂福利天堂| 夜夜嗨av一区二区三区中文字幕| 午夜精品久久久久久| 日韩一二三区视频| 久久高清福利视频| 亚洲永久免费av| 欧美电影免费观看网站| 久久婷婷国产麻豆91天堂| 欧美视频中文字幕在线| 欧美黄色免费网站| 黄色欧美日韩| 香蕉成人伊视频在线观看| 99国产精品久久久久久久成人热| 久久久精品五月天| 久久不射2019中文字幕| 国产精品vvv| 亚洲精品久久| 亚洲精品国产精品国自产在线 | 亚洲成色www8888| 国产目拍亚洲精品99久久精品| 亚洲人妖在线| 99国产精品一区| 你懂的视频一区二区| 裸体一区二区三区| 国内精品免费在线观看| 性做久久久久久| 亚洲免费视频成人| 欧美三日本三级少妇三99| 最新成人av网站| 99国产精品视频免费观看| 欧美91视频| 91久久精品国产91性色| 亚洲人人精品| 欧美电影美腿模特1979在线看 | 亚洲一区二区在线看| 欧美日韩高清在线一区| 亚洲精品一区二| 亚洲一区二区三区在线播放| 欧美日韩国产首页在线观看| 亚洲精品免费在线| 亚洲视屏在线播放| 国产精品理论片在线观看| 亚洲免费视频成人| 久久精品国产亚洲高清剧情介绍| 国产一区二区按摩在线观看| 久久精品国产99| 亚洲第一精品夜夜躁人人躁| a91a精品视频在线观看| 欧美天堂亚洲电影院在线观看| 亚洲天堂av在线免费观看| 午夜精彩视频在线观看不卡| 国产日韩欧美高清免费| 久久久久久久999精品视频| 欧美韩日一区二区| 制服丝袜激情欧洲亚洲| 国产美女精品| 久久一区二区三区四区| 亚洲茄子视频| 欧美在线视频一区二区三区| 一区二区三区在线免费观看| 裸体歌舞表演一区二区| 宅男噜噜噜66一区二区| 久久久久88色偷偷免费| 亚洲另类视频| 国产视频在线观看一区| 欧美fxxxxxx另类| 亚洲一区二区三区在线看| 久久色在线观看| 99国产精品久久久久老师| 国产精品三级久久久久久电影| 久久久久亚洲综合| 日韩午夜电影av| 久久综合色8888| 亚洲一区二区精品视频| 在线日韩精品视频| 国产精品海角社区在线观看| 久久男人资源视频| 一区二区三区四区国产| 欧美第十八页| 久久激情五月激情| 妖精视频成人观看www| 国一区二区在线观看| 欧美日韩一区二区在线观看| 久久精品一区二区三区不卡| 亚洲免费播放| 亚洲成色777777在线观看影院| 亚洲欧美一区二区三区在线| 亚洲精品久久久久久下一站| 国产性猛交xxxx免费看久久| 欧美日韩在线不卡一区| 久久尤物视频| 久久精品99久久香蕉国产色戒| 夜夜嗨av色综合久久久综合网| 免费在线观看日韩欧美| 欧美一级网站| 亚洲主播在线| 99在线视频精品| 亚洲欧洲日产国产网站| 狠狠色伊人亚洲综合成人| 国产精品一区二区在线| 国产精品成人播放| 欧美日韩精品欧美日韩精品一| 美女图片一区二区| 久久这里只有精品视频首页| 欧美中文字幕在线播放| 欧美夜福利tv在线| 亚洲欧美国产高清| 亚洲综合色在线| 亚洲综合色激情五月| 亚洲一本大道在线| 亚洲无吗在线| 午夜免费久久久久| 欧美一区二区三区四区高清| 午夜一区在线| 欧美一级电影久久| 欧美在线观看天堂一区二区三区| 亚洲欧美日韩爽爽影院| 午夜欧美大片免费观看 | 欧美国产视频一区二区| 欧美激情按摩在线| 亚洲成在线观看| 亚洲黄色视屏| 99亚洲一区二区| 亚洲一区二区精品| 午夜精品久久久久久久久| 亚洲欧洲av一区二区| 欧美一区二视频| 久久久综合精品| 老司机精品久久| 欧美日韩亚洲综合一区| 国产精品免费视频观看| 国产一级揄自揄精品视频| 黄色成人在线网址| 亚洲美女在线国产| 亚洲一级在线观看| 久久精品一区中文字幕| 欧美福利专区| 日韩视频二区| 欧美淫片网站| 欧美电影免费观看网站| 国产精品久久久久久久9999| 国产一区二区精品久久99| 亚洲欧洲一区二区在线播放| av不卡在线看| 久久理论片午夜琪琪电影网| 亚洲第一天堂无码专区| 亚洲午夜日本在线观看| 久久免费黄色| 欧美视频日韩视频| 在线观看91久久久久久| 一区二区三区精品视频在线观看| 欧美一区二区三区日韩视频| 欧美不卡一区| 亚洲一区二区三区欧美| 美国三级日本三级久久99| 国产精品乱码人人做人人爱| 亚洲激情电影中文字幕| 亚洲欧美中文另类| 亚洲欧洲日韩女同| 久久本道综合色狠狠五月| 欧美日韩日日骚| 亚洲高清在线| 欧美中文在线观看国产| 亚洲日韩欧美视频| 久久亚洲春色中文字幕| 国产精品视频男人的天堂| 日韩视频中文字幕| 免费成人黄色| 久久高清国产|