您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++的函數指針用法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++的函數指針用法”吧!
看C++代碼時看到了一段很新奇的用法, 回來剖析了一下, 感覺雖然原理很簡單還是值得記錄一下的。
代碼大概是這個樣子的:
class test {
public:
void a1(){printf("test::a1\n");};
}
int main()
{
test *t = new test();
void (test::*a)(void);
a = &test::a1;
(t->*a)();
}
以前在C++中用函數指針時,從來都反射性的去用靜態成員函數, 卻從來都沒想到原來普通的成員函數也是可以使用函數指針的。
仔細分析一下, 原理也早就知道。 無非就是this指針的事。
使用test對象的指針去調用某函數與普通的C函數指針惟一的區別就是, 會將test對象的指針作為this指針通過ecx寄存器來傳入, 那么所有的C++類成員函數在本質上也是通過ecx的值來訪問他們的成員變量。
在不反匯編的情況下, 為了更清晰的驗證一下上述結論, 加入了如下代碼:
void (*b)(void);
b = (void (*)(void))&test::a1;
b();
最后可以發現函數依然可以運行。
當然這里其實有點取巧,因為test::a1函數并沒有訪問類的成員變量, 所以我們可以將此成員函數直接作為普通的函數來調用。
如果test::a1函數訪問成員變量的話, 由于C函數調用時并沒有傳入this指針, 那么test::a1函數必將會由于隨機的ecx值而導致崩潰。
但是這段代碼已經足夠證明,&test::a1給出的是函數的絕對地址與普通的C函數的地址并無兩樣,那么調用b()和(t->*a)()的區別其實就在于是否傳入了this指針。
如果再有點hack精神, 其實可以去將test::a1函數更改為訪問成員變量, 然后在調用C函數前, 可以手動內嵌asm代碼來將ecx值強制改為t的指針值, 如果效果一樣, 那么即可完全證明上述結論。
感謝各位的閱讀,以上就是“C++的函數指針用法”的內容了,經過本文的學習后,相信大家對C++的函數指針用法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。