爲了找到this指針,編寫如下C++程序(main.cpp):
#include <stdio.h>
class A
{
public:
int m_Num;
A(void)
:m_Num(0xAB)
{
}
virtual void Func_F(void)
{
}
virtual void Func_G(void)
{
}
};
class B: public A
{
public:
virtual void Func_F(void)
{
int rCX = 0, rAX=0, rEBP8=0;
printf("this=0x%X\n", this);
asm volatile
(
"movl %%ecx,%0\n\t"
"movl %%eax,%1\n\t"
"movl 8(%%ebp),%2\n\t"
: "=r"(rCX), "=r"(rAX),"=r"(rEBP8)
: "r"(rCX), "r"(rAX),"r"(rEBP8)
: /* */
);
printf("Cur ECX=[0x%X] EAX=[0x%X] esp8=[0x%X] this=[0x%X]\n", rCX, rAX, rEBP8,this);
}
};
int main(int args, char ** argv)
{
B * pB = new B;
pB->Func_F();
return 0;
}
函數Func_F會打印出當前的ECX的數值和this指針的數值, 其中ECX的數值通過內嵌彙編語言獲取的,在Linux(Fedora 10) X86系統上使用G++編譯
g++ -o test main.cpp
運行編譯出的test文件,輸出結果如下:
[yfeng@work work]$ ./test
this=0x9C40008
Cur ECX=[0xBF80A5F8] EAX=[0x0] esp8=[0x9C40008] this=[0x9C40008]
從輸出結果可以很明顯的看到,this指針並沒有存放到ECX裏面,而是放在堆棧(ESP+8),(ESP+8)正是函數Func_F的第一個參數存放地址,可見類的this指針是作爲第一個參數傳遞給函數的。讀者可以使用G++產生的彙編代碼進行深入研究, 使用
g++ -s -save-temps main.cpp
產生出的中間文件“main.s"就是相應的彙編代碼。
結論: 可見,讀書不能盡信書,其中道理需要自己反覆實踐和體會。
聲明:這裏並不是說所有編譯器都會把this作爲第一個參數傳遞,其它編譯器或者同一編譯器的不同版本也許使用其它方法傳遞this指針。