C++基礎之this指針的詳解
關于C++中的this指針,建議大家看看這篇文章,《C++中的this指針》,供參考。
this指針是一個特殊的指針,當類的某個非靜態(tài)的成員函數(shù)在執(zhí)行時,就會存在this指針。它指向類的一個對象,且這個對象的某個成員函數(shù)正在被調用。
this指針的名字始終是this,而且總是作為隱含參數(shù)傳遞給每一個被聲明的成員函數(shù),例如:
- void Date::myFunc(Date* this);
實際編程時函數(shù)的聲明不需要包含這個參數(shù)。
當程序中調用某個對象的成員函數(shù)時,編譯器會把該對象的地址加入到參數(shù)列表中,感覺上就好象函數(shù)采用了上面所示的聲明,并且是用如下方式來調用的:
- dt.myFunc(& dt);
靜態(tài)成員函數(shù)不存在this指針。
當調用某個對象的成員函數(shù)時,編譯器把對象的地址傳遞給this指針,然后再調用該函數(shù)。因此,成員函數(shù)你對任何成員的調用實際上都隱式地使用了this指針。
1.以this指針作為返回值
使this指針可以允許成員函數(shù)返回調用對象給調用者。前面的程序中重載賦值運算符沒有返回值,因此不能用如下的形式對字符串進行賦值:
- a=b=c;
為了使重載的類賦值機制也能這樣方便,必須讓賦值函數(shù)返回賦值的結果,在這里就是目標對象。當賦值函數(shù)執(zhí)行時,其返回值也恰好是this指針所指的內容。下面的程序對前面那個程序進行了修改,讓重載賦值運算符返回了一個Date對象的引用。
- #include \"iostream.h\"
- #include \"string.h\"
- class Date
- {
- int mo,da,yr;
- char *month;
- public:
- Date(int m=0, int d=0, int y=0);
- ~Date();
- void operator=(const Date&);
- void display() const;
- };
- Date::Date(int m, int d, int y)
- {
- static char *mos[] =
- {
- \"January\",\"February\",\"March\",\"April\",\"May\",\"June\",
- \"July\",\"August\",\"September\",\"October\",\"November\",\"December\"
- };
- mo = m; da = d; yr = y;
- if (m != 0)
- {
- month = new char[strlen(mos[m-1])+1];
- strcpy(month, mos[m-1]);
- }
- else month = 0;
- }
- Date::~Date()
- {
- delete [] month;
- }
- void Date::display() const
- {
- if (month!=0) cout<<month<<\' \'<<da<<\",\"<<yr<<endl;
- }
- void Date::operator=(const Date& dt)
- {
- if (this != &dt)
- {
- mo = dt.mo;
- da = dt.da;
- yr = dt.yr;
- delete [] month;
- if (dt.month != 0)
- {
- month = new char [std::strlen(dt.month)+1];
- std::strcpy(month, dt.month);
- }
- else month = 0;
- }
- return *this;
- }
- int main()
- {
- Date birthday(8,11,1979);
- Date oldday,newday;
- oldday=newday=birthday;
- birthday.display();
- oldday.display();
- newday.display();
- return 0;
- }
2.在鏈表中使用this指針
在應用程序中,如果數(shù)據(jù)結構里有指向自身類型的成員,那么使用this指針會提供更多的方便。下面的程序中建立了一個類ListEntry的鏈表。
- #include \"iostream.h\"
- #include \"string.h\"
- class ListEntry
- {
- char* listvalue;
- ListEntry* preventry;
- public:
- ListEntry(char*);
- ~ListEntry() { delete [] listvalue; }
- ListEntry* PrevEntry() const { return preventry; };
- void display() const { cout<<endl<<listvalue; }
- void AddEntry(ListEntry& le) { le.preventry = this; }
- };
- ListEntry::ListEntry(char* s)
- {
- listvalue = new char[strlen(s)+1];
- strcpy(listvalue, s);
- preventry = 0;
- }
- int main()
- {
- ListEntry* prev = 0;
- while (1)
- {
- cout <<endl<<\"Enter a name(\'end\' when done): \";
- char name[25];
- cin >> name;
- if (strncmp(name, \"end\", 3) == 0) break;
- ListEntry* list = new ListEntry(name);
- if (prev != 0) prev->AddEntry(*list);
- prev = list;
- }
- while (prev != 0)
- {
- prev->display();
- ListEntry* hold = prev;
- prev = prev->PrevEntry();
- delete hold;
- }
- return 0;
- }
程序運行時,會提示輸入一串姓名,當輸入完畢后,鍵入\"end\",然后程序會逆序顯示剛才輸入的所有姓名。
程中ListEntry類含有一個字符串和一個指向前一個表項的指針。構造函數(shù)從對中獲取內存分配給字符串,并把字符串的內容拷貝到內存,然后置鏈接指針為NULL。析構函數(shù)將釋放字符串所占用的內存。
成員函數(shù)PrevEntry()返回指向鏈表前一個表項的指針。另一個成員函數(shù)顯示當前的表項內容。
成員函數(shù)AddEntry(),它把this指針拷貝給參數(shù)的preventry指針,即把當前表項的地址賦值給下一個表項的鏈接指針,從而構造了一個鏈表。它并沒有改變調用它的listEntry對象的內容,只是把該對象的地址賦給函數(shù)的參數(shù)所引用的那個ListEntry對象的preventry指針,盡管該函數(shù)不會修改對象的數(shù)據(jù),但它并不是常量型。這是因為,它拷貝對象的地址this指針的內容給一個非長常量對象,而編譯器回認為這個非常量對象就有可能通過拷貝得到的地址去修改當前對象的數(shù)據(jù),因此AddEntry()函數(shù)在聲明時不需要用const。
希望通過以上內容的介紹,能夠給你帶來幫助。