今天的話題比較有意思,如何獲取乙個非 static 成員函式的指標?考慮以下**:
c++**
class a
;
void a::foo(void)
也就是說,如何獲取 a::foo 的指標?
那位說了:這有何難?乙個 typedef 全搞定!
c++**
typedef
void (a::*fooptr)(void);
fooptr func = &a::foo;
且慢,我還沒說完呢。我要把這個指標用於 thunk 技術,所以我希望得到乙個 void* 型別的指標。這樣一來,如果再使用乙個型別轉換的話,那麼就會得到乙個 c2440 的編譯錯誤,因為 c++ 是強型別的,不允許我們胡作非為。
於是我們只能搞些歪門邪道了,且看:
方案一 彙編
c++**
void* func = null;
__asm
優點:效率高,無廢話。
缺點:可移植性差。
方案二 stdio
c++**
void* func = null;
char addr[9];
sprintf(addr, "%p", &a::foo);
sscanf(addr, "%p", &func);
優點:完全可移植。
缺點:效率低,而且有些無厘頭。
從方案二中我們可以發現,sprintf 的可變引數可以繞過型別檢查,於是我們得到了乙個相對而言更優雅、開銷更小的解決方案:
c++**
void* getaddr(void* useless, ...)
void* func = getaddr(null, &a::foo);
另外需要指出的是,對於 vc 的 debug 配置而言,以上的三種方式獲取的都不是 a::foo 的真實位址,而是 ilt 的位址。因此如果我們需要的是真實位址的話,還需要另外解析 ilt 表項的**。
目前為止最優雅的解決方案如下,由 likunkun 提供。
c++**
template
inline
void* pfun(t fun)
void *p = pfun(&a::foo);
2009 年 2 月 1 日補記,利用 union 的解決方案:
獲取成員函式的指標
今天的話題比較有意思,如何獲取乙個非 static 成員函式的指標?考慮以下 classa voida foo void 也就是說,如何獲取 a foo 的指標?那位說了 這有何難?乙個 typedef 全搞定!typedef void a fooptr void fooptrfunc a foo ...
C 中怎麼獲取類的成員函式的函式指標?
用乙個實際 來說明。class a static member void nonstatic nonstatic member virtual void virtualmember virtual member int main 可以參考 c primer 3rd 第532頁13.6指向類成員的指標...
指向成員函式的指標
指向成員函式的指標 取乙個非靜態成員函式的位址,如果該函式是nonvirtual,則得到的結果是它在記憶體中真正的位址。然而這個值也不是完全的,它也需要被繫結於某個class object的位址上,才能夠通過它呼叫該函式。所有的非靜態成員函式都需要物件的位址 以引數this指出 乙個指向成員函式的指...