您好,登錄后才能下訂單哦!
這篇文章給大家介紹成員函數指針的結構以及怎么與普通函數指針之間的轉換,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
通過內存拷貝(memcpy等)可以實現任意指針
間的強制轉換,但不能保證可以正常使用。
通過網上查找發現:
函數成員指針其實與普通成員指針不同,它除了包含函數本身地址以外還包含其他信息(例如是否為虛函數等),所以不能簡單的理解成員函數指針就是普通指針那樣一般占4字節,這個視編譯器不同而不同:例如在VS中,普通成員函數指針類似于
struct ptr{
int * addr;
};
而虛函數的結構比較復雜,它是通過this指針加索引的方式來獲取函數的真實地址,目前沒有完全明白,此不贅述。
這里提獲取成員函數真實地址的方法:
1 .普通成員函數
通過觀察不難發現結構體的首地址就是addr的首地址,所以成員函數的入口地址其實也就是函數指針的地址,但是C++出于類型安全的考慮不允許他們轉換成其他普通指針,如:
class test { public: void print(){} }; typedef void (test::*cfun)(); typedef void (*fun)(); cfun cf = &test::print; fun f= cf; //失敗,類型檢查 memcpy(&f,&cf,sizeof(fun)); f(); //成功
2. 虛函數
(1)通過虛函數表獲取
class test{ public: virtual void print(){} }; typedef void (test::*cfun)(); typedef void (*fun)(); test t; int **vptr = (int**)(&t); //vptr[0]獲取虛函數表地址 cfun f = vptr[0][0]; //后面那個零時虛函數在虛函數表中的索引,表示第一個虛函數 f(); ((fun) vptr[0][0])();
通常不能用&test::print獲取虛函數地址,即使獲取地址也是一個中間值或者總是返回0x1。
3. 通用的指針轉換函數
template<class T,class R> R convert(T t) { long addr = 0; memcpy(&addr,&t,sizeof(long)); return (R)(addr); }
但不能保證轉換的有效性。
關于成員函數指針的結構以及怎么與普通函數指針之間的轉換就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。