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

每天早晨叫醒你的不是鬧鐘,而是夢(mèng)想

  C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
  62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團(tuán)隊(duì)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

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

 解決方案

 這里的方案只支持一個(gè)模板參數(shù),但如果一些能夠如愿的話,隨著更多的編譯器完全實(shí)現(xiàn)C++標(biāo)準(zhǔn),以后將會(huì)支持動(dòng)態(tài)的模板參數(shù),比如“…”形式的模板參數(shù)列表(參見(jiàn)《C++ Templates, The Complete Guide》),那時(shí),我們就可以可以實(shí)現(xiàn)無(wú)需全部預(yù)定義的參數(shù)集合。(文中所有代碼的注釋為譯者加,下同。)

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

 模板(template)的使用非常方便,模板本身可被實(shí)例化為一個(gè)對(duì)象指針(object pointer)或者一個(gè)簡(jiǎn)單的類(lèi)(class)。當(dāng)作為對(duì)象指針使用時(shí),C++有另外一個(gè)令人痛苦的限制:operator() 不可以在指針未被解引用的情況下調(diào)用,對(duì)于這個(gè)限制,一個(gè)簡(jiǎn)便的但卻不怎么優(yōu)雅的解決方法在一個(gè)模板內(nèi)部增加一個(gè)execute方法(method),由這個(gè)方法從模板內(nèi)部來(lái)調(diào)用operator()。除了這一點(diǎn)不爽之外,實(shí)例化SinglarCallBack為一個(gè)對(duì)象指針將可以使你擁有一個(gè)由回調(diào)組成的vector,或者任何其他類(lèi)型的集合,這在事件驅(qū)動(dòng)程序設(shè)計(jì)中是非常需要的。
 假設(shè)以下兩個(gè)類(lèi)已經(jīng)存在,而且我們想讓methodB作為我們的回調(diào)方法,從代碼中我們可以看到當(dāng)傳遞一個(gè)class A類(lèi)的參數(shù)并調(diào)用methodB時(shí),methodB會(huì)調(diào)用A類(lèi)的output方法,如果你能在stdout上看到"I am class A :D",就說(shuō)明回調(diào)成功了。
 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;
     }
 };
 有兩種方法可以從一個(gè)對(duì)象指針上調(diào)用一個(gè)回調(diào)方法,較原始的方法是解引用(dereference)一個(gè)對(duì)象指針并運(yùn)行回調(diào)方法(即:operator()),第二個(gè)選擇是運(yùn)行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;
 }
 下面的代碼示范了怎樣將一個(gè)模板實(shí)例化成一個(gè)普通的對(duì)象并使用之。
 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;
 }
 更復(fù)雜的例子,一個(gè)回調(diào)模板可以像下面這樣使用:
 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;
}

下面這個(gè)例子比上面的又復(fù)雜一些,你可以混合從同一個(gè)公共基類(lèi)(base class)上繼承下來(lái)的不同的類(lèi)到一個(gè)容器中,于是你就可以調(diào)用位于繼承樹(shù)的最底層的類(lèi)的方法(most derived method)。(譯者注,C++的多態(tài)機(jī)制)
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;
}

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

posted on 2011-04-14 22:12 沛沛 閱讀(683) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 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>
            久久国产精品第一页| 亚洲国产日韩欧美| 亚洲一区二区三区影院| 亚洲国产欧美国产综合一区| 国产精品成人一区二区网站软件| 亚洲一区欧美二区| 亚洲欧美激情四射在线日| 国产精品久久久久一区二区三区共| 亚洲欧美国产精品va在线观看| 亚洲综合精品自拍| 一本久道综合久久精品| 亚洲校园激情| 激情久久影院| 亚洲麻豆一区| 国产亚洲一级高清| 亚洲国产精品一区制服丝袜| 国产一区二区在线观看免费| 亚洲综合国产| 亚洲免费在线观看视频| 欧美精品国产一区二区| 欧美在线国产精品| 免费观看亚洲视频大全| 亚洲在线网站| 欧美日精品一区视频| 久久综合成人精品亚洲另类欧美| 欧美精品一区二区三| 久久精品国产综合精品| 欧美激情一区二区三区成人| 亚洲丰满少妇videoshd| 国产欧美日韩免费看aⅴ视频| 欧美高清视频在线| 国产日产精品一区二区三区四区的观看方式 | 国产模特精品视频久久久久 | 久久久国产91| 欧美精品18videos性欧美| 欧美激情精品久久久六区热门| 欧美午夜一区二区福利视频| 免费在线观看日韩欧美| 国产精品高潮在线| 亚洲视频一区二区免费在线观看| 亚洲激情成人网| 欧美一区二区三区视频在线| 亚洲深夜激情| 欧美极品aⅴ影院| 一级日韩一区在线观看| 亚洲精品在线看| 久久久久久综合| 久久av资源网站| 黄色资源网久久资源365| 久热国产精品| 欧美大片免费观看| 中日韩高清电影网| 国产老女人精品毛片久久| 久久久亚洲一区| 99re66热这里只有精品4| 亚洲精品你懂的| 猛干欧美女孩| 欧美激情无毛| 亚洲免费在线| 亚洲国产一区二区精品专区| 欧美精品尤物在线| 午夜一区二区三视频在线观看 | 最新精品在线| 91久久午夜| 米奇777超碰欧美日韩亚洲| 亚洲黄网站黄| 欧美制服丝袜| 日韩视频―中文字幕| 欧美h视频在线| 亚洲一区二区三区成人在线视频精品| 亚洲午夜一区二区三区| 精品成人一区二区三区| 欧美人成免费网站| 久久久99爱| 亚洲国产va精品久久久不卡综合| 亚洲自拍偷拍色片视频| 亚洲国产福利在线| 欧美激情一区二区三区成人 | 欧美成人蜜桃| 亚洲精品久久7777| 国产精品99久久不卡二区| 国语自产精品视频在线看抢先版结局 | 亚洲精品一区久久久久久| 久久偷窥视频| 亚洲欧美综合国产精品一区| 国产精品亚洲综合| 久久精品国产精品亚洲精品| 欧美成人精品三级在线观看| 亚洲美女av在线播放| 韩国在线一区| 国产视频丨精品|在线观看| 久久欧美肥婆一二区| 亚洲激情国产| 欧美国产欧美综合| 鲁大师成人一区二区三区| 亚洲开发第一视频在线播放| 国产一区在线视频| 欧美成人精品在线视频| 久久久噜噜噜久久中文字免| 亚洲欧美一区二区原创| 欧美高清在线| 葵司免费一区二区三区四区五区| 先锋影音久久久| 亚洲国产综合在线看不卡| 国产午夜精品视频| 国产亚洲一区二区在线观看| 国产欧美一区二区三区沐欲| 国产精品视频网站| 国产伦精品一区二区三区高清版| 欧美体内谢she精2性欧美| 欧美日韩一区精品| 欧美一区二区在线免费播放| 亚洲欧美激情诱惑| 亚洲欧美日本国产专区一区| 亚洲午夜三级在线| 亚洲欧美一区二区原创| 香蕉乱码成人久久天堂爱免费| 亚洲欧美一区二区三区极速播放 | 亚洲自拍啪啪| 欧美一区二区高清在线观看| 欧美影院成人| 在线视频一区二区| 亚洲一区中文字幕在线观看| 亚洲一区久久久| 香蕉成人啪国产精品视频综合网| 欧美伊久线香蕉线新在线| 久久久久九九视频| 欧美va天堂| 欧美午夜在线一二页| 国产日韩欧美一区| 悠悠资源网久久精品| 国产亚洲精品久久久久久| 国产一区二区久久久| 亚洲电影视频在线| 一区二区在线看| 亚洲精品国久久99热| 亚洲午夜激情| 久久偷看各类wc女厕嘘嘘偷窃| 欧美 亚欧 日韩视频在线| 日韩视频一区二区三区在线播放| 亚洲欧美卡通另类91av| 久久这里有精品视频| 欧美色中文字幕| 精品99一区二区| 一区二区三区黄色| 一区二区三区国产精华| 久久丁香综合五月国产三级网站| 免费观看久久久4p| 一区二区三区高清| 久久精品国产99精品国产亚洲性色| 欧美激情一区二区在线 | 亚洲福利精品| 亚洲欧美日韩一区二区三区在线观看| 久久久噜噜噜久久中文字免| 久久精品一本久久99精品| 亚洲国产精品久久久久秋霞蜜臀| 亚洲综合首页| 欧美连裤袜在线视频| 国内精品视频久久| 亚洲综合激情| 亚洲国产天堂久久综合| 久久av一区二区三区漫画| 欧美视频第二页| 亚洲激情网站免费观看| 久久久久一区二区三区四区| 亚洲美女中文字幕| 欧美成人午夜激情| 一区二区亚洲精品| 欧美在线视频导航| aa级大片欧美| 欧美一区日本一区韩国一区| 欧美精品在线免费| 亚洲韩国一区二区三区| 久久精品一区四区| 亚洲尤物视频网| 欧美日韩在线电影| 日韩视频二区| 亚洲国产二区| 老司机午夜精品视频| 国产一区视频在线看| 性做久久久久久免费观看欧美| 日韩一区二区精品视频| 欧美mv日韩mv亚洲| 亚洲人成网站在线播| 欧美大片一区| 麻豆亚洲精品| 亚洲国产日韩一区二区| 免费观看欧美在线视频的网站| 久久国产直播| 狠狠色丁香婷综合久久| 久久精品亚洲一区二区三区浴池 | 欧美成人国产| 亚洲人成7777| 欧美激情视频一区二区三区免费| 久久综合99re88久久爱| 亚洲激情综合| 亚洲国产一区二区三区在线播 | 欧美日韩国产一中文字不卡| 国产日韩精品一区二区| 久久er精品视频|