--------------------------------------------------------------------------------
標(biāo)題: 如何使用類的成員方法指針?
作者: 葉飛虎
日期: 2009.03.22
--------------------------------------------------------------------------------
其實(shí),類方法調(diào)用原理很簡單,若知道如何使用C語言模擬類實(shí)現(xiàn)就知道怎么回事了,只
是這個(gè)工作由編譯器來做罷了。調(diào)用方法與調(diào)用函數(shù)的區(qū)別是在調(diào)用方法時(shí),編譯器把當(dāng)前
對象的指針當(dāng)做第一個(gè)參數(shù)傳入,其它參數(shù)的傳遞與函數(shù)沒有區(qū)別,也就說,這為提供回調(diào)
事件的方法指針提供一條方便之門。方法指針不能濫用,用好它可以使你的視野更加開闊!
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 // 調(diào)用 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 // 調(diào)用 C 方法
109 C.Func1(
); // <=> A.AF1(
);
110 C.Func2(
); // <=> B.BF2(
);
111
112 // ???

113
114 }
115
116 /* TKYFmtMemEvent - 格式化內(nèi)存項(xiàng)事件類 */
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 // 執(zhí)行 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 // 執(zhí)行 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 // 例子:如何設(shè)置事件方法指針
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
回調(diào)事件的方法指針需要C++編譯器支持,至少VC的不同版本及GCC編譯器都支持。
在VC6和VC2003中設(shè)置方法指針相對較寬松,VC2005之后就很嚴(yán)格了,如下:
FDemo.OnInitialize.Method = (TKYFmtMemEvent::TDoFormat)&TDemo::DoFormat;
這行代碼都被不同版本VC編譯器支持,但如下代碼就只能被VC6、VC2003支持:
FDemo.OnInitialize.Method = (TKYFmtMemEvent::TDoFormat)DoFormat;
其實(shí),類方法調(diào)用原理很簡單,若知道如何使用C語言模擬類實(shí)現(xiàn)就知道怎么回事了,只
是這個(gè)工作由編譯器來做罷了。不過不是什么方法都可以調(diào)用的,如:靜態(tài)方法就只能當(dāng)做
函數(shù)指針來用,而重載方法、虛方法等等是不可靠的,所以最好使用普通的類方法指針。
調(diào)用方法與調(diào)用函數(shù)的區(qū)別是在調(diào)用方法時(shí),編譯器把當(dāng)前對象的指針當(dāng)做第一個(gè)參數(shù)傳
入,其它參數(shù)的傳遞與函數(shù)沒有區(qū)別,也就說,這為提供回調(diào)事件的方法指針提供一條方便之門。
方法指針不能濫用,用好它可以使你的視野更加開闊!
posted on 2011-05-22 11:01
Kyee Ye 閱讀(401)
評論(0) 編輯 收藏 引用 所屬分類:
技巧雜集