C++this指針詳解

  之前對this指針誤解挺多的,在這裏單獨寫一篇進行總結,有不對之處,歡迎指正批評!html

1、問題

1.一個類中的不一樣對象在調用本身的成員函數時,其實它們調用的是同一段函數代碼,那麼成員函數如何知道要訪問哪一個對象的數據成員呢?ios

  沒錯,就是經過this指針。每一個對象都擁有一個this指針,this指針記錄對象的內存地址,當咱們調用成員函數時,成員函數默認第一個參數爲T* const register this,大多數編譯器經過ecx寄存器傳遞this指針,經過 this 這個隱式參數能夠訪問該對象的數據成員。程序員

2.類的成員函數爲何不能用static和const同時修飾?函數

  類中用const修飾的函數一般用來防止修改對象的數據成員,函數末尾的const是用來修飾this指針,防止在函數內對數據成員進行修改,而靜態函數中是沒有this指針的,沒法訪問到對象的數據成員,與C++ static語義衝突,因此不能。大數據

2、this指針注意點

1.C++中this關鍵字是一個指向對象本身的一個常量指針,不能給this賦值;this

2.只有成員函數纔有this指針,友元函數不是類的成員函數,沒有this指針;人工智能

3.一樣靜態函數也是沒有this指針的,靜態函數如同靜態變量同樣,不屬於具體的哪個對象;spa

4.this指針做用域在類成員函數內部,在類外也沒法獲取;指針

5.this指針並非對象的一部分,this指針所佔的內存大小是不會反應在sizeof操做符上的。code

3、this指針的使用

1.在類的非靜態成員函數中返回類對象自己的時候,直接使用 return *this,好比類的默認取址運算符重載函數,另外,也能夠返回*this的引用,這樣能夠像輸入輸出流那樣進行「級聯」操做;

2.修改類成員變量或參數與成員變量名相同時,如this->a = a (寫成a = a編譯不過);

3.在class定義時要用到類型變量自身時,由於這時候還不知道變量名,就用this這樣的指針來使用變量自身。

4、this指針探討

1.this指針是何時建立的? 

  對象new的過程當中建立的,具體哪一個階段有待進一步深刻了解。

2. this指針存放在何處?

  this指針會因編譯器不一樣而有不一樣的放置位置。多是棧,也多是寄存器,甚至全局變量。在彙編級別裏面,一個值只會以3種形式出現:當即數、寄存器值和內存變量值。不是存放在寄存器就是存放在內存中,它們並非和高級語言變量對應的。

3.爲何C++ NULL對象指針能夠調用非虛成員函數,而Java中卻不行?

  C++語言是靜態綁定的,這也是C++語言和Java語言的一個顯著區別。類的成員函數並不與特定對象綁定,全部成員函數共用一份成員函數體,當程序編譯後,成員函數的地址即已經肯定。另外,C++只關心你的指針類型,不關心指針指向的對象是否有效,C++要求程序員本身保證指針的有效性。何況在有些系統上,地址0也是有效的,理論上徹底能夠構造一個在地址0上的對象,因此C++中nullptr對象調用成員函數並沒有不可 。

  nullptr對象調用成員函數時,只要不訪問此對象獨有的內存部分,則程序正常運行,由於不會使用this,一旦訪問此對象的成員變量,則程序崩潰。固然nullptr調用虛方法是不能正常運行的(虛函數有虛表,會佔用內存空間),虛方法調用是依賴於this指針的。能夠這樣理解,你給函數傳遞了錯誤的參數,但在該函數內部並無使用該參數,因此其不影響函數的運行。能夠參考下面代碼:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class CPeople
 5 {
 6 public:
 7     CPeople(const std::string& name, int age)
 8       : mName(name), mAge(age){}
 9      ~CPeople();
10  
11     void Print()
12     {
13         std::cout << "show people info:" << std::endl;
14     }
15 
16     void PrintInfo()
17     {
18         std::cout << "name:" << mName << std::endl;
19         std::cout << "age:" << mAge << std::endl;
20     }
21  
22 private:
23  
24     std::string mName;
25     int mAge;
26  
27 };
28  
29 int main()
30 {
31     CPeople* jon = NULL;
32     jon->Print();  // 程序正常運行
33     jon->PrintInfo();  // 程序崩潰,訪問非法地址,此時mName和mAge並無分配空間
34     return 0;
35 }

 

5、總結

  引用網上關於this指針的一個經典回答:

  當你進入一個房子後,
  你能夠看見桌子、椅子、地板等,
  可是房子你是看不到全貌了。
  對於一個類的實例來講,
  你能夠看到它的成員函數、成員變量,
  可是實例自己呢?
  this是一個指針,它時時刻刻指向你這個實例自己。

  對this指針有了一個全面瞭解後,是否對C++ class理解也更深入一步?

  寫做,能讓人更深刻的瞭解事情的本質,慢慢積累,厚積薄發,加油!

 

做者:KeepHopes
出處:http://www.javashuo.com/article/p-rtkesrte-be.html
關於做者:專一C++,對大數據、人工智能領域頗感興趣,請多多賜教!
本文爲做者原創,版權歸做者和博客園共有,轉載或引用請註明出處,謝謝!
相關文章
相關標籤/搜索