C this指標(直戳本質)

2021-10-02 21:57:13 字數 2026 閱讀 7975

為了能讓大家看清 this 指標的本質,我們會先講一點 c++ 的歷史——c++ 程式到c程式的翻譯過程。

c++ 是在c語言的基礎上發展而來的,第乙個 c++ 的編譯器實際上是將 c++ 程式翻譯成c語言程式,然後再用c語言編譯器進行編譯。

c語言沒有類的概念,只有結構,函式都是全域性函式,沒有成員函式。翻譯時,將 class 翻譯成 struct、物件翻譯成結構變數是顯而易見的,但是對類的成員函式應該如何翻譯?對mycar.modify();這樣通過乙個物件呼叫成員函式的語句,又該如何翻譯呢?

c語言中只有全域性函式,因此成員函式只能被翻譯成全域性函式;mycar.modify();這樣的語句也只能被翻譯成普通的呼叫全域性函式的語句。那如何讓翻譯後的 modify 全域性函式還能作用在 mycar 這個結構變數上呢?答案就是引入「this 指標」。下面來看一段 c++ 程式到c 程式的翻譯。

c++程式:

class ccar

;void ccar::setprice(int p)

int main()

翻譯後的c程式(此程式應儲存為擴充套件名為 .c 的檔案後再編譯):

struct ccar

;void setprice(struct ccar* this, int p)

int main()

可以看出,類被翻譯成結構體,物件被翻譯成結構變數,成員函式被翻譯成全域性函式。但是c程式的全域性函式 setprice 比 c++ 的成員函式 selprice 多了乙個引數,就是struct ccar *thiscar.setprice(20000);被翻譯成setprice(&car, 20000);,後者在執行時,this 形參指向的正是 car 這個變數,因而達到了 setprice 函式作用在 car 變數上的效果。

思考題:以上翻譯還不完整,因為建構函式的作用沒有體現出來。思考建構函式應該如何翻譯。另外,靜態成員函式和靜態成員變數應如何翻譯?

實際上,現在的c編譯器從本質上來說也是按上面的方法來處理成員函式和對成員函式的呼叫的,即非靜態成員函式實際上的形參個數比程式設計師寫的多乙個。多出來的引數就是所謂的「this指標」。這個「this指標」指向了成員函式作用的物件,在成員函式執行的過程中,正是通過「ihis指標」才能找到物件所在的位址,因而也就能找到物件的所有非靜態成員變數的位址。

下面程式的執行結果能夠證明這一點:

#include using namespace std;

class a

};int main()

程式的輸出結果是:

hello

在上面的程式中,p 明明是乙個空指標,為何通過它還能正確呼叫 a 的成員函式 hello 呢?因為,參考上面 c++ 到c程式的翻譯,p->hello()實質上應該是hello(p),在翻譯後的 hello 函式中,cout 語句沒有用到 this 指標,因此依然可以輸出結果。如果 hello 函式中有對成員變數的訪問,則程式就會出錯。

c++ 規定,在非靜態成員函式內部可以直接使用 this 關鍵字,this 就代表指向該函式所作用的物件的指標。看下面的例子:

#include using namespace std;

class complex

complex addone()

};int main()

第 9 行,this 指標的型別是 complex*。因為 this 指標就指向函式所作用的物件,所以 this->rear 和 real 是完全等價的。*this代表函式所作用的物件,因此執行第 16 行,進入 addone 函式後,*this實際上就是 c1。因此的 c2 值會變得和 c1 相同。

因為靜態成員函式並不作用於某個物件,所以在其內部不能使用 this 指標;否則,這個 this 指標該指向哪個物件呢?

this指標 C this指標

this 是 c 中的乙個關鍵字,也是乙個 const 指標,不可以更改指向。指向當前物件,通過它可以訪問當前物件的所有成員。include includeusing namespace std class girlfriend void introduce introduce函式在編譯器看來是這個...

c this 指標詳解

首先來觀察一段 class myclass int data const void tmyclass 我們知道類的成員函式在記憶體只有乙份拷貝,而類的資料成員 不考慮靜態成員 是每個物件都有自己的乙份,所以上述 中obj1和obj2呼叫data函式是同乙個函式,但它們擁有各自的資料,所以輸出結果為0...

c this指標總結

1 限定被相似的名稱隱藏的成員 public class thisname public void getthisname string name,int num 2 將物件作為引數傳遞到別的方法中 public class thisff public string shuju public voi...