在C++中,每个对象中的数据成员都分别占有存储空间,如果对同一个类定义了n个对象,则有n组同样大小的的空间以存放n个对象中的数据成员。**但是,不同的对象都调用同一个函数的目标代码**。例如:
#include <iostream>
using namespace std;
class Data
{
public:
void InitData(int year, int month, int day);
void PrintData();
private:
int _year;
int _month;
int _day;
};
void Data::InitData(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Data::PrintData()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
int main()
{
Data a, b, c;
a.InitData(2016, 10, 7);
a.PrintData();
b.InitData(2016, 10, 8);
b.PrintData();
c.InitData(2016, 10, 9);
c.PrintData();
system("pause");
return 0;
}
那么,当不同对象的成员函数引用数据成员时,怎么能保证引用的时所指向的对象的成员呢?
在每一个成员函数都包括一个特殊的指针,这个指针的名字是固定的,称为this。**它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。**例如,当调用成员函数a.InitData(2016, 10, 7)时,编译系统就把对象a的起始地址赋给this指针,于是在成员函数引用数据成员时,就按照this的指向找到对象a的数据成员。例如InitData函数要初始化_year = year;_month = month;_day = day;的值,实际上是执行:
this->_year = year;
this->_month = month;
this->_day = day;
由于当前this指针指向a,因此相当于执行:
a._year = year;
a._month = month;
a._day = day;
同样有b.InitData(2016, 10, 8);时,编译器就把对象b的起始地址赋给成员函数InitData的this指针,此时
this->_year = year;
this->_month = month;
this->_day = day;
就是
b._year = year;
b._month = month;
b._day=day
this指针是隐式使用的,它是作为参数被传递给成员函数的。本来,成员函数InitData的定义
void Data::InitData(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
C++编译器把它处理为
void Data::InitData(Data* this, int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
即在成员函数的形参表列中增加一个this指针。在调用该成员函数时,实际上使用以下方式调用的:
a.InitData(&a, 2016,10,7);
将对象a的地址传给形参this指针。然后按照this指针的指向去引用其他成员。
需要说明:这些都是编译系统自动实现的,编程序者不必认为地在形参中增加this指针,也不必将对象a的地址传给this指针。