说到这个this指针,有一种不吐不快的压抑。
请看现在主流的市面上的教材讲this指针的一个惯用手法,下面是一个惯常用例。
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int x_, int y_);
void Print();
};
Point::Point(int x_, int y_)
{
x = x_;
y = y_;
}
void Point::Print()
{
cout << "(" << x << "," << y << ")" << endl;
}
int main()
{
Point p1(10,20);
Point p2(30,40);
p1.Print();
p2.Print();
}
该程序的输出结果如下:
作者通常会由这个结果引发疑问----为什么同样是调用Print()函数,程序就知道第一个Print()函数是输出第一个点的坐标,第二个Print()函数就知道要输出第二个点的坐标?作者的解答一般都是因为有一个隐含的this指针的存在才区分了这二者。
但是,这个问题不是读者想到的,是作者自己想到的。即便没接触过C++,即便不知道this指针的人看到这两个对象调用的Print()函数输出不同的结果应该也不会有这种疑问。
为什么说读者不会有这种疑问呢?现在我们假设我们还没有真正接触过C++,更不知道this,我们只是有C的基础来看这个程序。很明显的一个事实是,Point类定义了两个变量p1和p2,p1.Print()必然表示p1这个对象调用了属于p1这个对象的类的成员,同理p2.Print()必然调用对应p2这个对象的成员,问题来了,如果这二者都能混淆起来的话,试问类所定义的多个对象之间如何独立的引用属于自己的成员或者方法?如果这个问题都不能解决,类的引出还有什么意义?这就如同一个简单的类int,我们都知道int只是表示单一的一个数的数据类型,int a和int b必然表示同一类型的两个不同的对象并且用a和b去区分,至于a和b所对应的内容是不可能混淆的。C++提供“类”这个东西仅仅只是为了满足程序员定制属于自己的新的数据类型而已,所以对比int这简单的数据类型就可以看出端倪。
this指针是什么?官方的解释是:this是指向当前对象的一个默认的指针。
问题来了,请问this在哪里?刚才的程序丝毫没有提及this啊。所以,这里必须强强调的是,this是一个隐含的指针,如果我们不去使用它,编译器会处理这个东西,如果想要看看this的真面目,就上面的例子来看的话,应该是这样的:
p1.Print(&p1);
p2.Print(&p2);
...
...
void Point::Print(Point *const this)
{
cout<<"("<<this->x<<","<<this->y<<")"<<endl";
}
这种写法是把我们读者的思维显式的表达出来了,其实可以理解为编译器就是这样处理的,而这个其实就是this指针的实质,有了这样一种方式,同一个类的不同对象是不可能产生成员的调用发生混淆的行为的。
下面来看如何利用隐式的this指针来做意见实际的事情,当然既然要用this指针了,程序里面肯定会把他写出来。
注意:我们想要利用this指针来干一件具体的事情总是基于这样一个事实----this指针总是默认的指向当前的这个对象。
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int x_, int y_);
void Print();
void Copy(Point poi);
};
Point::Point(int x_, int y_)
{
x = x_;
y = y_;
}
void Point::Print()
{
cout << "(" << x << "," << y << ")" << endl;
}
void Point::Copy(Point poi)
{
*this = poi;
}
int main()
{
Point p1(10,20);
Point p2(30,40);
Point px(0,0);
p1.Print();
p2.Print();
p1.Copy(px);
p2.Copy(px);
p1.Print();
p2.Print();
}
第12行我们声明了一个Copy()函数;
第23行给出了Copy()函数的函数体;
第34,35行是本程序的精华部分,利用刚才讲到的,p1.Copy()这个函数摆在这里,意为通过对象p1调用成员函数Copy(),那么很明显进入函数体之后this指针默认就是指向p1这个对象的,Copy函数体内部执行将px对象的值给了this地址所指向的存储单元,毫无疑问px的内容将会赋给p1这个对象。
p2.Copy(px)同上。
如此以来,最终p1,p2的内容必将被px的内容所取代。
请看程序输出结果:
结果表明,这个程序执行的机理和我们预想的方式是一致的。