### 隐藏的 this 指针

对于类的非静态成员，每一个对象都有自己的一份拷贝，即每个对象都有自己的数据成员和成员函数。

例如，每一个对象都有自己的一份拷贝。

class CBook //定义一个 CBook 类

{

public:

int m_Pages; //定义一个数据成员

void OutputPages() //定义一个成员函数

{

printf("%d\n",m_Pages); //输出信息

}

};

int main(int argc, char* argv[])

{

CBook vbBook,vcBook; //定义 2 个 CBook 类对象

vbBook.m_Pages = 512; //设置 vbBook 对象的成员数据

vcBook.m_Pages = 570; //设置 vcBook 对象的成员数据

vbBook.OutputPages(); //调用 OutputPages 方法输出 vbBook 对象的数据成员

vcBook.OutputPages(); //调用 OutputPages 方法输出 vcBook 对象的数据成员

return 0;

}

执行上述代码，效果如图 1 所示。

图 1 访问对象的数据成员

从图 1 中可以发现，vbBook 和 vcBook 两个对象均有自己的数据成员 m_Pages，在调用 OutputPages 成员函数时输出的均是自己的数据成员。在 OutputPages 成员函数中只是访问了 m_Pages 数据成员，每个对象在调用 OutputPages 方法时是如何区分自己的数据成员呢？答案是通过 this 指针。在每个类的成员函数（非静态成员函数）中都隐含包含一个 this 指针，指向被调用对象的指针，其类型为当前类类型的指针类型，在 const 方法中，为当前类类型的 const 指针类型。当 vbBook 对象调用 OutputPages 成员函数时，this 指针指向 vbBook 对象，当 vcBook 对象调用 OutputPages 成员函数时，this 指针指向 vcBook 对象。在 OutputPages 成员函数中，用户可以显式地使用 this 指针访问数据成员。例如：

void OutputPages()

{

printf("%d\n",this->m_Pages); //使用 this 指针访问数据成员

}

实际上，编译器为了实现 this 指针，在成员函数中自动添加了 this 指针对数据成员或方法，类似于上面的 OutputPages 方法。

说明：为了将this指针指向当前调用对象，并在成员函数中能够使用，在每个成员函数中都隐含包含一个this指针作为函数参数，并在函数调用时将对象自身的地址隐含作为实际参数传递。

例如，以 OutputPages 成员函数为例，编译器将其定义为：

void OutputPages(CBook* this) //隐含添加 this 指针

{

printf("%d\n",this->m_Pages);

}

在对象调用成员函数时，传递对象的地址到成员函数中。以“vc.OutputPages();”语句为例，编译器将其解释为“vbBook.OutputPages(&vbBook);”。这样，就使得 this 指针合法，并能够在成员函数中使用。