|
本文介绍的是C++中的this指针,希望对你有帮助,一起来看。
关于C++中的this指针,建议大家看看这篇文章,《C++中的this指针》,供参考。
this指针是一个特殊的指针,当类的某个非静态的成员函数在执行时,就会存在this指针。它指向类的一个对象,且这个对象的某个成员函数正在被调用。
this指针的名字始终是this,而且总是作为隐含参数传递给每一个被声明的成员函数,例如:
- void Date::myFunc(Date* this);
实际编程时函数的声明不需要包含这个参数。
当程序中调用某个对象的成员函数时,编译器会把该对象的地址加入到参数列表中,感觉上就好象函数采用了上面所示的声明,并且是用如下方式来调用的:
静态成员函数不存在this指针。
当调用某个对象的成员函数时,编译器把对象的地址传递给this指针,然后再调用该函数。因此,成员函数你对任何成员的调用实际上都隐式地使用了this指针。
1.以this指针作为返回值
使this指针可以允许成员函数返回调用对象给调用者。前面的程序中重载赋值运算符没有返回值,因此不能用如下的形式对字符串进行赋值:
为了使重载的类赋值机制也能这样方便,必须让赋值函数返回赋值的结果,在这里就是目标对象。当赋值函数执行时,其返回值也恰好是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指针
在应用程序中,如果数据结构里有指向自身类型的成员,那么使用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类含有一个字符串和一个指向前一个表项的指针。构造函数从对中获取内存分配给字符串,并把字符串的内容拷贝到内存,然后置链接指针为NULL。析构函数将释放字符串所占用的内存。
成员函数PrevEntry()返回指向链表前一个表项的指针。另一个成员函数显示当前的表项内容。
成员函数AddEntry(),它把this指针拷贝给参数的preventry指针,即把当前表项的地址赋值给下一个表项的链接指针,从而构造了一个链表。它并没有改变调用它的listEntry对象的内容,只是把该对象的地址赋给函数的参数所引用的那个ListEntry对象的preventry指针,尽管该函数不会修改对象的数据,但它并不是常量型。这是因为,它拷贝对象的地址this指针的内容给一个非长常量对象,而编译器回认为这个非常量对象就有可能通过拷贝得到的地址去修改当前对象的数据,因此AddEntry()函数在声明时不需要用const。
希望通过以上内容的介绍,能够给你带来帮助。
|
|