以前對this指針誤解挺多的,在這里單獨寫一篇進行總結,有不對之處,歡迎指正批評!
一、問題
1.一個類中的不同對象在調用自己的成員函數時,其實它們調用的是同一段函數代碼,那么成員函數如何知道要訪問哪個對象的數據成員呢?
沒錯,就是通過this指針。每個對象都擁有一個this指針,this指針記錄對象的內存地址,當我們調用成員函數時,成員函數默認第一個參數為T* const register this,大多數編譯器通過ecx寄存器傳遞this指針,通過 this 這個隱式參數可以訪問該對象的數據成員。
2.類的成員函數為什么不能用static和const同時修飾?
類中用const修飾的函數通常用來防止修改對象的數據成員,函數末尾的const是用來修飾this指針,防止在函數內對數據成員進行修改,而靜態函數中是沒有this指針的,無法訪問到對象的數據成員,與C++ static語義沖突,所以不能。
二、this指針注意點
1.C++中this關鍵字是一個指向對象自己的一個常量指針,不能給this賦值;
2.只有成員函數才有this指針,友元函數不是類的成員函數,沒有this指針;
3.同樣靜態函數也是沒有this指針的,靜態函數如同靜態變量一樣,不屬於具體的哪一個對象;
4.this指針作用域在類成員函數內部,在類外也無法獲取;
5.this指針並不是對象的一部分,this指針所占的內存大小是不會反應在sizeof操作符上的。
三、this指針的使用
1.在類的非靜態成員函數中返回類對象本身的時候,直接使用 return *this,比如類的默認取址運算符重載函數,另外,也可以返回*this的引用,這樣可以像輸入輸出流那樣進行“級聯”操作;
2.修改類成員變量或參數與成員變量名相同時,如this->a = a (寫成a = a編譯不過);
3.在class定義時要用到類型變量自身時,因為這時候還不知道變量名,就用this這樣的指針來使用變量自身。
四、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 }
五、總結
引用網上關於this指針的一個經典回答:
對this指針有了一個全面了解后,是否對C++ class理解也更深刻一步?
寫作,能讓人更深入的了解事情的本質,慢慢積累,厚積薄發,加油!
作者:KeepHopes
出處:https://www.cnblogs.com/yuwanxian/p/10988736.html
關於作者:專注C++,對大數據、人工智能領域頗感興趣,請多多賜教!
本文為作者原創,版權歸作者和博客園共有,轉載或引用請注明出處,謝謝!
