C++基礎(chǔ)之this指針的詳解
關(guān)于C++中的this指針,建議大家看看這篇文章,《C++中的this指針》,供參考。
this指針是一個(gè)特殊的指針,當(dāng)類的某個(gè)非靜態(tài)的成員函數(shù)在執(zhí)行時(shí),就會(huì)存在this指針。它指向類的一個(gè)對(duì)象,且這個(gè)對(duì)象的某個(gè)成員函數(shù)正在被調(diào)用。
this指針的名字始終是this,而且總是作為隱含參數(shù)傳遞給每一個(gè)被聲明的成員函數(shù),例如:
- void Date::myFunc(Date* this);
實(shí)際編程時(shí)函數(shù)的聲明不需要包含這個(gè)參數(shù)。
當(dāng)程序中調(diào)用某個(gè)對(duì)象的成員函數(shù)時(shí),編譯器會(huì)把該對(duì)象的地址加入到參數(shù)列表中,感覺上就好象函數(shù)采用了上面所示的聲明,并且是用如下方式來(lái)調(diào)用的:
- dt.myFunc(& dt);
靜態(tài)成員函數(shù)不存在this指針。
當(dāng)調(diào)用某個(gè)對(duì)象的成員函數(shù)時(shí),編譯器把對(duì)象的地址傳遞給this指針,然后再調(diào)用該函數(shù)。因此,成員函數(shù)你對(duì)任何成員的調(diào)用實(shí)際上都隱式地使用了this指針。
1.以this指針作為返回值
使this指針可以允許成員函數(shù)返回調(diào)用對(duì)象給調(diào)用者。前面的程序中重載賦值運(yùn)算符沒有返回值,因此不能用如下的形式對(duì)字符串進(jìn)行賦值:
- a=b=c;
為了使重載的類賦值機(jī)制也能這樣方便,必須讓賦值函數(shù)返回賦值的結(jié)果,在這里就是目標(biāo)對(duì)象。當(dāng)賦值函數(shù)執(zhí)行時(shí),其返回值也恰好是this指針?biāo)傅膬?nèi)容。下面的程序?qū)η懊婺莻€(gè)程序進(jìn)行了修改,讓重載賦值運(yùn)算符返回了一個(gè)Date對(duì)象的引用。
- #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指針
在應(yīng)用程序中,如果數(shù)據(jù)結(jié)構(gòu)里有指向自身類型的成員,那么使用this指針會(huì)提供更多的方便。下面的程序中建立了一個(gè)類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;
- }
程序運(yùn)行時(shí),會(huì)提示輸入一串姓名,當(dāng)輸入完畢后,鍵入\"end\",然后程序會(huì)逆序顯示剛才輸入的所有姓名。
程中ListEntry類含有一個(gè)字符串和一個(gè)指向前一個(gè)表項(xiàng)的指針。構(gòu)造函數(shù)從對(duì)中獲取內(nèi)存分配給字符串,并把字符串的內(nèi)容拷貝到內(nèi)存,然后置鏈接指針為NULL。析構(gòu)函數(shù)將釋放字符串所占用的內(nèi)存。
成員函數(shù)PrevEntry()返回指向鏈表前一個(gè)表項(xiàng)的指針。另一個(gè)成員函數(shù)顯示當(dāng)前的表項(xiàng)內(nèi)容。
成員函數(shù)AddEntry(),它把this指針拷貝給參數(shù)的preventry指針,即把當(dāng)前表項(xiàng)的地址賦值給下一個(gè)表項(xiàng)的鏈接指針,從而構(gòu)造了一個(gè)鏈表。它并沒有改變調(diào)用它的listEntry對(duì)象的內(nèi)容,只是把該對(duì)象的地址賦給函數(shù)的參數(shù)所引用的那個(gè)ListEntry對(duì)象的preventry指針,盡管該函數(shù)不會(huì)修改對(duì)象的數(shù)據(jù),但它并不是常量型。這是因?yàn)椋截悓?duì)象的地址this指針的內(nèi)容給一個(gè)非長(zhǎng)常量對(duì)象,而編譯器回認(rèn)為這個(gè)非常量對(duì)象就有可能通過拷貝得到的地址去修改當(dāng)前對(duì)象的數(shù)據(jù),因此AddEntry()函數(shù)在聲明時(shí)不需要用const。
希望通過以上內(nèi)容的介紹,能夠給你帶來(lái)幫助。