• <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>
            隨筆-3  評論-5  文章-13  trackbacks-0

            --------------------------------------------------------------------------------
            標題: 如何使用類的成員方法指針?
            作者: 葉飛虎
            日期: 2009.03.22
            --------------------------------------------------------------------------------

               其實,類方法調用原理很簡單,若知道如何使用C語言模擬類實現就知道怎么回事了,只
            是這個工作由編譯器來做罷了。調用方法與調用函數的區別是在調用方法時,編譯器把當前
            對象的指針當做第一個參數傳入,其它參數的傳遞與函數沒有區別,也就說,這為提供回調
            事件的方法指針提供一條方便之門。方法指針不能濫用,用好它可以使你的視野更加開闊!

              1 /* TObject - 基類 */
              2 
              3 class TObject
              4 {
              5 };
              6 
              7 
              8 /* TDemoA - A 類 */
              9 
             10 class TDemoA
             11 {
             12 public:
             13    TDemoA();
             14    virtual ~TDemoA();
             15 
             16    void  AF1(void* AParam);
             17    void  AF2(const char* AStr, long AValue);
             18 
             19    // ???  
             20 };
             21 
             22 /* TDemoB - B 類 */
             23 
             24 class TDemoB
             25 {
             26 public:
             27    TDemoB();
             28    virtual ~TDemoB();
             29 
             30    void  BF1(void* AParam);
             31    void  BF2(const char* AStr, long AValue);
             32 
             33    // ???  
             34 };
             35 
             36 /* TDemoC - C 類 */
             37 
             38 class TDemoC
             39 {
             40 public:
             41    // TOnFunc1 事件類型
             42    typedef void (TObject::*TDoFunc1)(void* AParam);
             43    typedef struct
             44    {
             45       TDoFunc1          Method;
             46       void*             Object;
             47    } TOnFunc1;
             48 
             49    // TOnFunc2 事件類型
             50    typedef void (TObject::*TDoFunc2)(const char* AStr, long AValue);
             51    typedef struct
             52    {
             53       TDoFunc2          Method;
             54       void*             Object;
             55    } TOnFunc2;
             56 
             57 public:
             58    TDemoC();
             59    virtual ~TDemoC();
             60 
             61    // Func1
             62    void  Func1(void* AParam)
             63    {
             64       if (OnFunc1.Method != NULL)
             65          ((TObject*)OnFunc1.Object->*OnFunc1.Method)(AParam);
             66    }
             67 
             68    // Func2
             69    void  Func2(const char* AStr, long AValue)
             70    {
             71       if (OnFunc2.Method != NULL)
             72          ((TObject*)OnFunc2.Object->*OnFunc2.Method)(AStr, AValue);
             73    }
             74 
             75    // 事件
             76    TOnFunc1    OnFunc1;
             77    TOnFunc1    OnFunc2;
             78 };
             79 
             80 
             81 // 例子
             82 TDemoA A;
             83 TDemoB B;
             84 TDemoC C;
             85 
             86 int demo()
             87 {
             88    // ???  
             89 
             90    C.OnFunc1.Object  = &B;
             91    C.OnFunc1.Method  = (TDemoC::TDoFunc1)&TDemoB::BF1;
             92 
             93    C.OnFunc2.Object  = &A;
             94    C.OnFunc2.Method  = (TDemoC::TDoFunc2)&TDemoA::AF2;
             95 
             96    // 調用 C 方法
             97    C.Func1();     // <=> B.BF1();
             98    C.Func2();     // <=> A.AF2();
             99 
            100    // ???  
            101 
            102    C.OnFunc1.Object  = &A;
            103    C.OnFunc1.Method  = (TDemoC::TDoFunc1)&TDemoA::AF1;
            104 
            105    C.OnFunc2.Object  = &B;
            106    C.OnFunc2.Method  = (TDemoC::TDoFunc2)&TDemoB::BF2;
            107 
            108    // 調用 C 方法
            109    C.Func1();     // <=> A.AF1();
            110    C.Func2();     // <=> B.BF2();
            111 
            112    // ???  
            113 
            114 }
            115 
            116 /* TKYFmtMemEvent - 格式化內存項事件類 */
            117 
            118 class TKYFmtMemEvent
            119 {
            120 public:
            121    // TOnFormat 事件類型
            122    typedef void (TObject::*TDoFormat)(void* AItem, Word ASize);
            123    typedef struct
            124    {
            125       TDoFormat         Method;
            126       void*             Object;
            127    } TOnFormat;
            128 
            129 public:
            130    TKYFmtMemEvent()  { Clear(); }
            131    ~TKYFmtMemEvent() { Clear(); }
            132 
            133    // 清除
            134    void  Clear();
            135 
            136    // 執行 OnInitialize 事件
            137    void  DoInitialize(void* AItem, Word ASize)
            138    {
            139       if (OnInitialize.Method != NULL)
            140          ((TObject*)OnInitialize.Object->*OnInitialize.Method)(AItem, ASize);
            141    }
            142 
            143    // 執行 OnFinalize 事件
            144    void  DoFinalize(void* AItem, Word ASize)
            145    {
            146       if (OnFinalize.Method != NULL)
            147          ((TObject*)OnFinalize.Object->*OnFinalize.Method)(AItem, ASize);
            148    }
            149 
            150    // 事件
            151    TOnFormat   OnInitialize;
            152    TOnFormat   OnFinalize;
            153 
            154 protected:
            155 private:
            156 };
            157 
            158 // 例子:如何設置事件方法指針
            159 void TDemo::SetEvent()
            160 {
            161    FDemo.OnInitialize.Object = this;
            162    FDemo.OnInitialize.Method = (TKYFmtMemEvent::TDoFormat)&TDemo::DoFormat;
            163 
            164    // ???  
            165 }
            166 
            167 // FDemo 的 OnInitialize 事件方法
            168 void TDemo::DoFormat(void* AItem, Word ASize)
            169 {
            170    // ???  
            171 }
            172 


                回調事件的方法指針需要C++編譯器支持,至少VC的不同版本及GCC編譯器都支持。
            在VC6和VC2003中設置方法指針相對較寬松,VC2005之后就很嚴格了,如下:
            FDemo.OnInitialize.Method = (TKYFmtMemEvent::TDoFormat)&TDemo::DoFormat;

               這行代碼都被不同版本VC編譯器支持,但如下代碼就只能被VC6、VC2003支持:
            FDemo.OnInitialize.Method = (TKYFmtMemEvent::TDoFormat)DoFormat;

               其實,類方法調用原理很簡單,若知道如何使用C語言模擬類實現就知道怎么回事了,只
            是這個工作由編譯器來做罷了。不過不是什么方法都可以調用的,如:靜態方法就只能當做
            函數指針來用,而重載方法、虛方法等等是不可靠的,所以最好使用普通的類方法指針。

               調用方法與調用函數的區別是在調用方法時,編譯器把當前對象的指針當做第一個參數傳
            入,其它參數的傳遞與函數沒有區別,也就說,這為提供回調事件的方法指針提供一條方便之門。

               方法指針不能濫用,用好它可以使你的視野更加開闊!



            posted on 2011-05-22 11:01 Kyee Ye 閱讀(401) 評論(0)  編輯 收藏 引用 所屬分類: 技巧雜集
            色综合合久久天天综合绕视看| 国内精品久久久久久久久电影网| 久久99精品久久久久久不卡| 久久久噜噜噜久久中文字幕色伊伊| 久久久久女教师免费一区| 久久久久国产精品| 久久青草国产手机看片福利盒子| 欧美亚洲国产精品久久高清| 亚洲香蕉网久久综合影视| 热久久国产精品| 亚洲国产精品无码久久青草 | 国产免费福利体检区久久| 久久久青草久久久青草| 伊人久久大香线蕉精品| 国产精品美女久久久网AV| 久久人人爽人人爽人人片AV麻豆| 国产免费久久精品99久久| 欧美久久一级内射wwwwww.| 国产精品久久新婚兰兰| 久久w5ww成w人免费| 情人伊人久久综合亚洲| 日产精品久久久久久久| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久国产精品一区| 久久婷婷五月综合成人D啪| 91精品国产色综合久久| 久久久久综合中文字幕 | 777午夜精品久久av蜜臀| 精品久久久久久无码人妻蜜桃| 97久久精品国产精品青草| 久久高潮一级毛片免费| 久久97久久97精品免视看| 久久噜噜久久久精品66| 色婷婷综合久久久久中文| 日韩久久无码免费毛片软件| 香蕉99久久国产综合精品宅男自| 久久成人18免费网站| 中文字幕无码精品亚洲资源网久久| 2021久久精品免费观看| 久久久久国产精品人妻| 精品欧美一区二区三区久久久|