***************************************************
更多精彩,歡迎進入:http://shop115376623.taobao.com
***************************************************
關于C++中的this指針,建議大家看看這篇文章,《C++中的this指針》,供參考。
this指針是一個特殊的指針,當類的某個非靜態的成員函數在執行時,就會存在this指針。它指向類的一個對象,且這個對象的某個成員函數正在被調用。
this指針的名字始終是this,而且總是作為隱含參數傳遞給每一個被聲明的成員函數,例如:
實際編程時函數的聲明不需要包含這個參數。
?
當程序中調用某個對象的成員函數時,編譯器會把該對象的地址加入到參數列表中,感覺上就好象函數采用了上面所示的聲明,并且是用如下方式來調用的:
靜態成員函數不存在this指針。
?
當調用某個對象的成員函數時,編譯器把對象的地址傳遞給this指針,然后再調用該函數。因此,成員函數你對任何成員的調用實際上都隱式地使用了this指針。
1.以this指針作為返回值
使this指針可以允許成員函數返回調用對象給調用者。前面的程序中重載賦值運算符沒有返回值,因此不能用如下的形式對字符串進行賦值:
為了使重載的類賦值機制也能這樣方便,必須讓賦值函數返回賦值的結果,在這里就是目標對象。當賦值函數執行時,其返回值也恰好是this指針所指的內容。下面的程序對前面那個程序進行了修改,讓重載賦值運算符返回了一個Date對象的引用。
?
2.在鏈表中使用this指針
在應用程序中,如果數據結構里有指向自身類型的成員,那么使用this指針會提供更多的方便。下面的程序中建立了一個類ListEntry的鏈表。
程序運行時,會提示輸入一串姓名,當輸入完畢后,鍵入\"end\",然后程序會逆序顯示剛才輸入的所有姓名。
?
程中ListEntry類含有一個字符串和一個指向前一個表項的指針。構造函數從對中獲取內存分配給字符串,并把字符串的內容拷貝到內存,然后置鏈接指針為NULL。析構函數將釋放字符串所占用的內存。
成員函數PrevEntry()返回指向鏈表前一個表項的指針。另一個成員函數顯示當前的表項內容。
成員函數AddEntry(),它把this指針拷貝給參數的preventry指針,即把當前表項的地址賦值給下一個表項的鏈接指針,從而構造了一個鏈表。它并沒有改變調用它的listEntry對象的內容,只是把該對象的地址賦給函數的參數所引用的那個ListEntry對象的preventry指針,盡管該函數不會修改對象的數據,但它并不是常量型。這是因為,它拷貝對象的地址this指針的內容給一個非長常量對象,而編譯器回認為這個非常量對象就有可能通過拷貝得到的地址去修改當前對象的數據,因此AddEntry()函數在聲明時不需要用const。
希望通過以上內容的介紹,能夠給你帶來幫助。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
this指針只能在一個類的成員函數中調用,它表示當前對象的地址。下面是一個例子: void Date::setMonth( int mn ) { month = mn; // 這三句是等價的 this->month = mn; (*this).month = mn; } 1. this只能在成員函數中使用。 全局函數,靜態函數都不能使用this。 實際上,成員函數默認第一個參數為T* const register this。 如: class A{public: int func(int p){}}; 其中,func的原型在編譯器看來應該是: int func(A* const register this, int p); 2. 由此可見,this在成員函數的開始前構造的,在成員的結束后清除。 這個生命周期同任一個函數的參數是一樣的,沒有任何區別。 當調用一個類的成員函數時,編譯器將類的指針作為函數的this參數傳遞進去。如: A a; a.func(10); 此處,編譯器將會編譯成: A::func(&a, 10); 嗯,看起來和靜態函數沒差別,對嗎?不過,區別還是有的。編譯器通常會對this指針做一些優化的,因此,this指針的傳遞效率比較高--如vc通常是通過ecx寄存器來傳遞this參數。3. 回答 #1:this指針是什么時候創建的? this在成員函數的開始執行前構造的,在成員的執行結束后清除。
#2:this指針存放在何處? 堆,棧,全局變量,還是其他? this指針會因編譯器不同,而放置的位置不同。可能是棧,也可能是寄存器,甚至全局變量。
#3:this指針如何傳遞給類中函數的?綁定?還是在函數參數的首參數就是this指針.那么this指針又是如何找到類實例后函數的? this是通過函數參數的首參數來傳遞的。this指針是在調用之前生成的。類實例后的函數,沒有這個說法。類在實例化時,只分配類中的變量空間,并沒有為函數分配空間。自從類的函數定義完成后,它就在那兒,不會跑的。
#4:this指針如何訪問類中變量的/? 如果不是類,而是結構的話,那么,如何通過結構指針來訪問結構中的變量呢?如果你明白這一點的話,那就很好理解這個問題了。 在C++中,類和結構是只有一個區別的:類的成員默認是private,而結構是public。 this是類的指針,如果換成結構,那this就是結構的指針了。#5:我們只有獲得一個對象后,才能通過對象使用this指針,如果我們知道一個對象this指針的位置可以直接使用嗎? this指針只有在成員函數中才有定義。因此,你獲得一個對象后,也不能通過對象使用this指針。所以,我們也無法知道一個對象的this指針的位置(只有在成員函數里才有this指針的位置)。當然,在成員函數里,你是可以知道this指針的位置的(可以&this獲得),也可以直接使用的。
#6:每個類編譯后,是否創建一個類中函數表保存函數指針,以便用來調用函數? 普通的類函數(不論是成員函數,還是靜態函數),都不會創建一個函數表來保存函數指針的。只有虛函數才會被放到函數表中。 但是,既使是虛函數,如果編譯器能明確知道調用的是哪個函數,編譯器就不會通過函數表中的指針來間接調用,而是會直接調用該函數。# 7:這些編譯器如何做到的?8:能否模擬實現? 知道原理后,這兩個問題就很容易理解了。 其實,模擬實現this的調用,在很多場合下,很多人都做過。 例如,系統回調函數。系統回調函數有很多,如定時,線程啊什么的。舉一個線程的例子: class A
{
int n; public: static void run(void* pThis)
{A* this_ = (A*)pThis;this_->process();} void process(){}};main()
{A a;_beginthread( A::run, 0, &a );}這里就是定義一個靜態函數來模擬成員函數。也有許多C語言寫的程序,模擬了類的實現。如freetype庫等等。 其實,有用過C語言的人,大多都模擬過。只是當時沒有明確的概念罷了。 如: typedef struct student{ int age; int no; int scores; }Student; void initStudent(Student* pstudent); void addScore(Student* pstudent, int score); ... 如果你把 pstudent改成this,那就一樣了。它相當于: class Student{ public: int age; int no; int scores; void initStudent(); void addScore(int score); }const常量可以有物理存放的空間,因此是可以取地址的///this指針是在創建對象前創建. this指針放在棧上,在編譯時刻已經確定. 并且當一個對象創建后,并且運行整個程序運行期間只有一個this指針