日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【转】C++ this指针(直戳本质)

發布時間:2025/3/15 c/c++ 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】C++ this指针(直戳本质) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://c.biancheng.net/view/170.html

?

為了能讓大家看清 this 指針的本質,我們會先講一點 C++ 的歷史——C++ 程序到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
  • {
  • public:
  • int price;
  • void SetPrice(int p);
  • };
  • ?
  • void CCar::SetPrice(int p)
  • {
  • price= p;
  • }
  • int main()
  • {
  • CCar car;
  • car.SetPrice(20000);
  • return 0;
  • }
  • class CCar { public:int price;void SetPrice(int p); };void CCar::SetPrice(int p) {price= p; } int main() {CCar car;car.SetPrice(20000);return 0; }

    翻譯后的C程序(此程序應保存為擴展名為 .c 的文件后再編譯):

  • struct CCar
  • {
  • int price;
  • };
  • void SetPrice(struct CCar* this, int p)
  • {
  • this->price = p;
  • }
  • int main()
  • {
  • struct CCar car;
  • SetPrice(&car, 20000);
  • return 0;
  • }
  • struct CCar {int price; }; void SetPrice(struct CCar* this, int p) {this->price = p; } int main() {struct CCar car;SetPrice(&car, 20000);return 0; }

    可以看出,類被翻譯成結構體,對象被翻譯成結構變量,成員函數被翻譯成全局函數。但是C程序的全局函數 SetPrice 比 C++ 的成員函數 SelPrice 多了一個參數,就是struct CCar *this。car.SetPrice(20000);被翻譯成SetPrice(&car, 20000);,后者在執行時,this 形參指向的正是 car 這個變量,因而達到了 SetPrice 函數作用在 car 變量上的效果。

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

    this 指針的作用

    實際上,現在的C編譯器從本質上來說也是按上面的方法來處理成員函數和對成員函數的調用的,即非靜態成員函數實際上的形參個數比程序員寫的多一個。多出來的參數就是所謂的“this指針”。這個“this指針”指向了成員函數作用的對象,在成員函數執行的過程中,正是通過“Ihis指針”才能找到對象所在的地址,因而也就能找到對象的所有非靜態成員變量的地址。

    下面程序的運行結果能夠證明這一點:

  • #include <iostream>
  • using namespace std;
  • class A
  • {
  • int i;
  • public:
  • void Hello(){ cout << "hello" << endl; }
  • };
  • int main()
  • {
  • A* p = NULL;
  • p -> Hello();
  • }
  • #include <iostream> using namespace std; class A {int i; public:void Hello(){ cout << "hello" << endl; } }; int main() {A* p = NULL;p -> Hello(); }sing namespace std; class A {int i; public:void Hello(){ cout << "hello" << endl; } }; int main() {A* p = NULL;p -> Hello(); }

    程序的輸出結果是:
    hello

    在上面的程序中,p 明明是一個空指針,為何通過它還能正確調用 A 的成員函數 Hello 呢?因為,參考上面 C++ 到C程序的翻譯,P->Hello()實質上應該是Hello(p),在翻譯后的 Hello 函數中,cout 語句沒有用到 this 指針,因此依然可以輸出結果。如果 Hello 函數中有對成員變量的訪問,則程序就會出錯。

    C++ 規定,在非靜態成員函數內部可以直接使用 this 關鍵字,this 就代表指向該函數所作用的對象的指針。看下面的例子:

  • #include <iostream>
  • using namespace std;
  • class Complex {
  • public:
  • double real, imag;
  • Complex(double r, double i) : real(r), imag(i) {}
  • Complex AddOne()
  • {
  • this->real++;
  • return *this;
  • }
  • };
  • int main()
  • {
  • Complex cl(1, 1), c2(0, 0);
  • c2 = cl.AddOne();
  • cout << c2.real << "," << c2.imag << endl; //輸出 2,1
  • return 0;
  • }
  • #include <iostream> using namespace std; class Complex { public:double real, imag;Complex(double r, double i) : real(r), imag(i) {}Complex AddOne(){this->real++;return *this;} }; int main() {Complex cl(1, 1), c2(0, 0);c2 = cl.AddOne();cout << c2.real << "," << c2.imag << endl; //輸出 2,1return 0; }

    第 9 行,this 指針的類型是 Complex*。因為 this 指針就指向函數所作用的對象,所以 this->rear 和 real 是完全等價的。*this代表函數所作用的對象,因此執行第 16 行,進入 AddOne 函數后,*this實際上就是 c1。因此的 c2 值會變得和 c1 相同。

    因為靜態成員函數并不作用于某個對象,所以在其內部不能使用 this 指針;否則,這個 this 指針該指向哪個對象呢?

    總結

    以上是生活随笔為你收集整理的【转】C++ this指针(直戳本质)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。