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