对于类对象,我们一定会直觉的认为肯定会比一般的数据类型大很多才是。为什么呢?可能有的人就可以很容易的举出相应的例子。比如说:对象包含了数据成员和成员函数。这样的一个实体能不大吗?常规理解对象确实很大,它不单单只有数据,而且还有函数来着。但是直觉却总是有例外的时候,其实编译器只维护了类的所有对象的一个函数副本。你可以用sizeof()函数来计算一下类或类的对象的大小。你会发现他们确实只包含了数据,而没有函数。有的人可能要问了,为什么这样做啊?其实相当简单,成员函数是不会在程序运行中改变的,如果每个对象都维护着这样一个不变的东西,那可想而知内存的占用会有多大。所有编译器相当明智的把它抽离出来,单独维护一个副本。又有人会问了,这样好是好,但是有个严重的问题啊!如果编译器维护着所有对象的一个函数副本,函数如何对特定的的对象起作用啊(也就是成员函数如何找准要服务的对象)。这里就引出了我们今天的主角了,this指针就是用来专门定位函数要操作的是哪个对象实体。
代码示例:
#include <iostream>
using namespace std;class Test{
public:
Test(int);
void print()const;//const声明的函数,意思是不会改变对象的状态
private:
int x;
};Test::Test( int value)//默认构造函数
:x(value)//初始化列表
{
}void Test::print() const
{
cout<<"x = "<<x<<endl;直接打印,隐式的this->指针调用
cout<<"this.x = "<<this->x<<endl;//显示this指针调用
cout<<"(*this).x = "<<(*this).x<<endl;//this指针对象来调用x
}int main(){
Test my(12);//调用构造函数,来初始化my对象
my.print();//调用相应的打印函数
}
执行结果:
x = 12
this.x = 12
(*this).x = 12
总结:编译器调用对象的函数的时候( 如main函数中的 my.print()调用 ),会把当前对象的this指针(每个对象都有一个指向自己的this指针,这个指针占用的大小并不计算在对象内,而是由编译器维护着)隐式的传给相应的函数,然后调用函数内this指针指向的数据成员来完成特定对象的状态修改。这就是用一份副本的函数来操作所有的对象的背后机制。也就是说函数内修改的数据成员前,都隐式的含有this->指针(此指针指向要修改的对象实体)。