C++封裝 之 this指標
阿新 • • 發佈:2021-08-25
this指標
概念
- this指標的作用:避免函式引數與資料成員重名
- this指標就是指向物件自身資料的指標,代表物件本身的地址
- 成員函式通過this指標訪問到對應的資料成員。
- 編譯時,編譯器自動為每個引數列表都加了this指標,所以程式設計師可以省略引數列表中的this指標
例項
- 定義一個Array類
- 資料成員:m_iLen表示陣列長度
- 成員函式:建構函式、解構函式、封裝函式、資訊輸出函式
demo1.cpp原始碼
#include<iostream> #include<stdlib.h> using namespace std; /************************************************************ * demo1.cpp 中類的資料成員(m_iLen)與成員函式的引數(len)不重名 * *********************************************************/ class Array{ public: Array(int len); //建構函式 ~Array(); //解構函式 void setLen(int x); int getLen(); void printfInfo(); private: int m_iLen; }; Array::Array(int len){ m_iLen = len; } Array::~Array(){ } void Array::setLen(int len){ m_iLen = len; } int Array::getLen(){ return m_iLen; } void Array::printfInfo(){ cout << "m_iLen = " << m_iLen << endl; } /****************** 測試主函式 ******************************/ int main(){ Array arr1(4); cout << arr1.getLen()<<endl; arr1.printfInfo(); system("pause"); return 0; }
執行結果
4
m_iLen = 4
demo2.cpp原始碼
#include<iostream> #include<stdlib.h> using namespace std; /************************************************************ * demo2.cpp 中類的資料成員(Len)與成員函式的引數(len)重名 !!! 執行錯誤 * *********************************************************/ class Array{ public: Array(int len); //建構函式 ~Array(); //解構函式 void setLen(int x); int getLen(); void printfInfo(); private: int len; //資料成員(Len)與成員函式的引數(len)重名 }; Array::Array(int len){ len = len; //編譯器會疑惑是將引數賦值給資料成員,還是將資料成員賦值給引數 } Array::~Array(){ } void Array::setLen(int len){ len = len; } int Array::getLen(){ return len; } void Array::printfInfo(){ cout << "len = " << len << endl; } /****************** 測試主函式 ******************************/ int main(){ Array arr1(4); cout << arr1.getLen()<<endl; arr1.printfInfo(); system("pause"); return 0; } /******************************* 執行結果(錯誤): 4201131 len = 4201131 *******************************/
執行結果(錯誤)
4201131
len = 4201131
demo3.cpp原始碼
#include<iostream> #include<stdlib.h> using namespace std; /************************************************************ * demo3.cpp 使用this指標解決資料成員(Len)與成員函式的引數(len)重名的問題,執行結果正確 * *********************************************************/ class Array{ public: Array(int len); //建構函式 ~Array(); //解構函式 void setLen(int x); int getLen(); void printfInfo(); private: int len; //資料成員(Len)與成員函式的引數(len)重名 }; Array::Array(int len){ this->len = len; // 新增this指標 ,編譯器不會再疑惑是將引數賦值給資料成員,還是將資料成員賦值給引數 } Array::~Array(){ } void Array::setLen(int len){ this->len = len; // 新增this指標 } int Array::getLen(){ return len; } void Array::printfInfo(){ cout << "len = " << len << endl; } /****************** 測試主函式 ******************************/ int main(){ Array arr1(4); cout << arr1.getLen()<<endl; arr1.printfInfo(); system("pause"); return 0; }
執行結果(正確)
4
len = 4
this指標的特殊用法
修改函式printfInfo():
在函式printfInfo()的宣告和定義中,將返回型別改為Array,並在printfInfo()的定義中返回this指標 ,事實上返回型別後面需要加&或*,後面再講到。
int printfInfo(){
cout << "len = " << m_iLen << endl;
}
修改為:
Array Array::printfInfo(){ // 修改printfInfo()函式的返回值為Array
cout << "len = " << len << endl;
return *this; // 返回this指標
}
由於函式printfInfo()返回了this指標,所以理論上語句 arr1.printfInfo().setLen(8) 相當於arr1.setLen(8) ,也就是該語句修改資料成員len為8,測試主函式如下:
int main(){
Array arr1(4);
arr1.printfInfo().setLen(8); //printfInfo()函式中返回了arr1物件的this指標,這裡相當於arr1.setLen(8)
cout << arr1.getLen()<<endl; //檢查上一條語句是否修改了資料成員len的值,執行結果發現len的值並沒有改變, 為什麼呢?
return 0;
}
執行結果(len修改不成功):
len = 4
4
- Q : 為什麼語句arr1.printfInfo().setLen(8)並沒有修改len的值?
- A : 這是因為printfInfo()函式是Array型別的,返回的this指標指向了一個新的Array物件(一個臨時物件),而不是原來的物件arr1
- Q : 如果希望printfInfo()返回的this指標指向arr1 ,該怎麼辦呢?
- A : 在printfInfo()函式的返回型別後加引用,即Array& Array::printfInfo()
demo4.cpp原始碼
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo4.cpp this指標的特殊用法,修改成員函式 printfInfo()的返回型別,返回this指標
* *********************************************************/
class Array{
public:
Array(int len);
~Array();
void setLen(int x);
int getLen();
Array& printfInfo(); //修改printfInfo()函式的返回型別為Array,並加 &
private:
int len; //資料成員(Len)與成員函式的引數(len)重名
};
Array::Array(int len){
this->len = len; // this指標
}
Array::~Array(){
}
void Array::setLen(int len){
this->len = len; //this指標
}
int Array::getLen(){
return len;
}
Array& Array::printfInfo(){ // 修改printfInfo()函式的返回值為Array,並加 &
cout << "len = " << len << endl;
return *this; // 返回this指標
}
/****************** 測試主函式 ******************************/
int main(){
Array arr1(4);
arr1.printfInfo().setLen(8); //修改資料成員len
cout << arr1.getLen()<<endl; //檢查上一條語句是否修改了資料成員len的值
system("pause");
return 0;
}
執行結果(len被成功修改):
len = 4
8
繼續修改函式setLen():
Array& Array::setLen(int len){
this->len = len; //this指標
return *this;
}
測試主函式:
int main(){
Array arr1(4);
arr1.printfInfo().setLen(8).printfInfo(); //setLen()後面直接呼叫其他成員函式
//cout << arr1.getLen()<<endl; //不需要該語句了
return 0;
}
執行結果:
len = 4
len = 8
把引用修改為指標
demo6.cpp原始碼
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo6.cpp this指標的特殊用法 把引用修改為指標
* *********************************************************/
class Array{
public:
Array(int len);
~Array();
Array* setLen(int x); //函式的返回型別為Array ,並加指標
int getLen();
Array* printfInfo(); //函式的返回型別為Array ,並加指標
private:
int len; //資料成員(Len)與成員函式的引數(len)重名
};
Array::Array(int len){
this->len = len; // this指標
}
Array::~Array(){
}
Array* Array::setLen(int len){
this->len = len; //this指標
return this;
}
int Array::getLen(){
return len;
}
Array* Array::printfInfo(){ // 修改printfInfo()函式的返回值為Array,並加指標
cout << "len = " << len << endl;
return this; // 返回this指標,這裡不需要星號了
}
/****************** 測試主函式 ******************************/
int main(){
Array arr1(4);
//arr1.printfInfo().setLen(8).printfInfo();
arr1.printfInfo()->setLen(8)->printfInfo(); //改成指標的呼叫方式
system("pause");
return 0;
}
執行結果
len = 4
len = 8