《C++面向对象高效编程(第2版)》——2.16 识别成员函数的目标对象
本節書摘來自異步社區出版社《C++面向對象高效編程(第2版)》一書中的第2章,第2.26節,作者: 【美】Kayshav Dattatri,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。
2.16 識別成員函數的目標對象
C++面向對象高效編程(第2版)
在編寫成員函數(構造函數、析構函數、操作符等)的代碼時,如何顯式表示調用該成員函數的對象?或者,如果需要,如何顯式返回目標對象(target object)的值?在成員函數內部,如何訪問調用該成員函數的對象中的數據成員?
這就是this指針發揮作用的地方。類的每個成員函數都有一個特殊的指針——this。這個this指針內含調用成員函數的對象的地址(即this指針總是指向目標對象)。this指針只在成員函數內部有效,this是C++中的關鍵字。
this指針的類型是“指向成員函數所屬類的指針”,也可以說“this的類型是類名”。在成員函數內部,this指針指向調用該成員函數的類實例。
編譯器對待成員函數并沒有什么特別。實際上,編譯器就像實現普通函數那樣實現成員函數,但是,它會專門對成員函數進行名稱重整(name mangling)以確保其唯一性。每個成員函數接受的第一個參數就是this指針。盡管程序員從未顯式聲明this指針,但是它一定存在。this指針通常是每個(非靜態)成員函數隱含的第一個參數,編譯器在每個成員函數的聲明中都會插入這個隱含的參數。為了說明這個概念,顯式聲明this指針如下,Print()成員函數應是:
void TInt::Print(const TInt* this) {cout << "0x" << _mostSignificantPart << ",0x" << _leastSignificantPart; }``` 實際上,this指針的聲明在已重整函數名(mangled function name)中可見。因此,TInt::Print應該是:void Print_3TIntFv(const TInt* this)
{
cout << "0x" << this->_mostSignificantPart << ", 0x" <<
this->_leastSignificantPart;
}`
一旦離開成員函數,this名稱將不再有效。
hand是否一定要使用this指針來引用目標對象中的成員?
不是所有情況都需要這樣做。只有在成員函數使用該類成員(數據成員或成員函數)的非限定(unqualified name)名時,才意味著使用this指針。如果在成員函數內部引用類的成員,編譯器會在每條表達式中均插入this指針(如果用戶沒有這樣做)?;仡橮rint()函數,可以這樣改寫:
void TInt::Print() {cout << "0x" << this->_mostSignificantPart << ", 0x" <<_leastSignificantPart; }``` `this- >_mostSignificantPart`表達式使用this指針顯式訪問數據成員_`mostSignificantPart`。`this- >_mostSignificantPart`表達式的意思是:this指針指向該對象中的 `_mostSignificantPart`數據成員。this指針只是成員函數的一個參數(但存在一些限制,將在其他地方討論),可以像使用成員函數的其他參數那樣使用this指針。甚至在2.15節的Print()實現中(沒有顯式使用this指針引用成員),編譯器也會將`_mostSignificantPart`表達式自動展開為`this- >_mostSignificantPart`表達式。在如下代碼段中,TInt aInt;
aInt.Print();`
對象aInt調用Print()(即向對象aInt發送Print()消息)。在Print()函數中this指針將指向aInt。
由于this是指向對象的指針,因此,如果要使用this指針獲得整個對象,我們必須使用操作符對this指針解引用(de-reference)為*this。正如其他指針那樣,this內部存放的是對象的地址,this則是該對象的值。
this指針的概念非C++獨享。OOP語言在涉及接收消息的對象時,使用不同的名稱。如Smalltalk稱為Self,Eiffel稱之為Current。
C++:
現在,把我們的注意力轉到TInt類的一些操作符函數上。
// +操作符的實現 TInt TInt::operator+(const TInt& operand) const// TInt 是該操作符函數的返回類型 {/*用于計算操作數和TInt數之和的代碼,TInt數調用+操作符函數,this指針指向TInt 數。該函數計算*this和操作數之和,并將計算結果以新的TInt數返回,未修改*this或操作數(因此用const限定符)。算法如下:1.加上 _leastSignificantPart部分并保存進位位元(carry bit)2.使用進位位元加上 _mostSignificantPart部分3.把(1)和(2)儲存在臨時TInt數中4.按值方式返回臨時TInt數*/TInt result = *this; // ① 調用復制構造函數unsigned char carry = 0;// 加上 _leastSignificant部分并檢查進位result._leastSignificantPart += operand.GetLeastSignificantPart();if ( result._leastSignificantPart < operand.GetLeastSignificantPart() )carry = 1;// 帶進位加上 _mostSignificantresult._mostSignificantPart += carry + operand.GetMostSignificantPart();return (result); }// 構造函數的框架TInt::TInt(long msp, unsigned long lsp){// 將傳遞給構造函數的值復制至相應的數據成員中 _leastSignificantPart = lsp;_mostSignificantPart = msp; }``` 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的《C++面向对象高效编程(第2版)》——2.16 识别成员函数的目标对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《树莓派用户指南(第3版)》——2.1
- 下一篇: 《C++代码设计与重用》——2.5 浅拷