標籤:this null hello 成員變數 靜態成員函數 std 就是 正是 ble
背景:
c++是在c語言的基礎上發展而來的,第一個c++的編譯器實際上是將c++程式翻譯成c語言程式,然後再用c語言編譯器進行編譯。c語言沒有類的概念,只有結構,函數都是全域函數,沒有成員函數。翻譯時,將class翻譯成struct、對象翻譯成結構變數是顯而易見的,但是對類的成員函數應該如何翻譯?對“my.modify();”這樣通過一個對象調用成員函數的語句,又該如何翻譯呢?
c語言只有全域函數,因此成員函數只能被翻譯成全域函數;“my.modify();”這樣的語句也只能翻譯成普通的調用全域函數的語句。那如何讓翻譯後的modify全域函數還能作用在my這個結構變數上呢?答案是引入“this指標”。
樣本:
下面來看一段c++程式到c程式的翻譯。
c++程式:
class CCar{ public: int price; void SetPrice(int p);};void CCar::SetPrice(int p){ price=p;}int main(){ CCar car; car.SetPrice(20000);}
翻譯後的c程式:
struct CCar{ int price;};void SetPrice(CCar* this,int p){ this->price=p;}int main(){ struct CCar car; SetPrice(&car,20000);}
可以看出,類被翻譯成結構體,對象被編譯成結構變數,成員函數被翻譯成全域函數。但是c程式的全域函數SetPrice比c++的成員函數SetPrice多了一個參數,就是“CCar*this”。“car.SetPrice(20000);”被翻譯成“SetPrice(&car,20000);”,後者在執行時,this形參指向的正是car這個變數,因而達到了SetPrice函數作用在car變數上的效果。
this指標的作用:
實際上,現在的c++編譯器從本質上來說也是按上面的方法來處理成員函數和對成員函數的調用的,即非靜態成員函數實際上的形參個數比程式員寫的多一個。多出來的參數就是所謂的“this指標”。這個”this指標“指向了成員函數作用的對象,在成員函數執行的過程中,正是通過“this指標”才能找到對象所在的地址,因而也就能找到對象的所有非靜態成員變數的地址。
樣本:
#incldue<iostream>using namespace std;class A{ int i; public: void Hello(){cout<<"hello"<<endl;}};int main(){ A*p=NULL: p->Hello();}
程式的輸出結果是:
hello
在上面的程式中,p明明是一個null 指標,但它還是能正確調用A的成員函數Hello,因為,參考上面c++到c程式的白泥臆,“p->Hello()”實質上應該是“Hello(p)”,在翻譯後的Hello函數中,cout語句沒有用到this指標,因此依然可以輸出結果。如果Hello函數中有對成員變數的訪問,則程式就會出錯。
this指標的使用:
c++規定,在非靜態成員函數內部可以直接使用this關鍵字,this就代表指向該函數所作用的對象的指標。
樣本:
#include<iostream>using namespace std;class A{ public:double real,imga;A(double r,double i):real(r),imga(i){} A addone(){ this->real++; return *this; }};int main(){ A c1(1,1),c2(0,0); c2=c1.addone();cout<<c2.real<<","<<c2.imga<<endl;}
輸出為 2,1
第9行,this指標的類型是A*。因為this指標就指向函數所作用的對象,所以this->real和real是完全等價的。“*this”代表函數所作用的對象,因此執行第16行,進入addone函數後,“*this”實際上就是c1。因此c2的值會變得和c1相同。
注意:
因為靜態成員函數並不作用於某個對象,所以在其內部不能使用this指標。
新標準c++程式設計
轉寄請註明出處
this指標------新標準c++程式設計