概念
- this指针的作用:避免函数参数与数据成员重名
- this指针就是指向对象自身数据的指针,代表对象本身的地址
- 成员函数通过this指针访问到对应的数据成员。
- 编译时,编译器自动为每个参数列表都加了this指针,所以程序员可以省略参数列表中的this指针
实例
- 定义一个Array类
- 数据成员:m_iLen表示数组长度
- 成员函数:构造函数、析构函数、封装函数、信息输出函数
demo1.cpp源码
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo1.cpp 中类的数据成员(m_iLen)与成员函数的参数(len)不重名
* *********************************************************/
class Array{
public:
Array(int len); //构造函数
~Array(); //析构函数
void setLen(int x);
int getLen();
void printfInfo();
private:
int m_iLen;
};
Array::Array(int len){
m_iLen = len;
}
Array::~Array(){
}
void Array::setLen(int len){
m_iLen = len;
}
int Array::getLen(){
return m_iLen;
}
void Array::printfInfo(){
cout << "m_iLen = " << m_iLen << endl;
}
/****************** 测试主函数 ******************************/
int main(){
Array arr1(4);
cout << arr1.getLen()<<endl;
arr1.printfInfo();
system("pause");
return 0;
}
运行结果
4
m_iLen = 4
demo2.cpp源码
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo2.cpp 中类的数据成员(Len)与成员函数的参数(len)重名 !!! 运行错误
* *********************************************************/
class Array{
public:
Array(int len); //构造函数
~Array(); //析构函数
void setLen(int x);
int getLen();
void printfInfo();
private:
int len; //数据成员(Len)与成员函数的参数(len)重名
};
Array::Array(int len){
len = len; //编译器会疑惑是将参数赋值给数据成员,还是将数据成员赋值给参数
}
Array::~Array(){
}
void Array::setLen(int len){
len = len;
}
int Array::getLen(){
return len;
}
void Array::printfInfo(){
cout << "len = " << len << endl;
}
/****************** 测试主函数 ******************************/
int main(){
Array arr1(4);
cout << arr1.getLen()<<endl;
arr1.printfInfo();
system("pause");
return 0;
}
/*******************************
运行结果(错误):
4201131
len = 4201131
*******************************/
运行结果(错误)
4201131
len = 4201131
demo3.cpp源码
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo3.cpp 使用this指针解决数据成员(Len)与成员函数的参数(len)重名的问题,运行结果正确
* *********************************************************/
class Array{
public:
Array(int len); //构造函数
~Array(); //析构函数
void setLen(int x);
int getLen();
void printfInfo();
private:
int len; //数据成员(Len)与成员函数的参数(len)重名
};
Array::Array(int len){
this->len = len; // 添加this指针 ,编译器不会再疑惑是将参数赋值给数据成员,还是将数据成员赋值给参数
}
Array::~Array(){
}
void Array::setLen(int len){
this->len = len; // 添加this指针
}
int Array::getLen(){
return len;
}
void Array::printfInfo(){
cout << "len = " << len << endl;
}
/****************** 测试主函数 ******************************/
int main(){
Array arr1(4);
cout << arr1.getLen()<<endl;
arr1.printfInfo();
system("pause");
return 0;
}
运行结果(正确)
4
len = 4
this指针的特殊用法
修改函数printfInfo():
在函数printfInfo()的声明和定义中,将返回类型改为Array,并在printfInfo()的定义中返回this指针 ,事实上返回类型后面需要加&或*,后面再讲到。
int printfInfo(){
cout << "len = " << m_iLen << endl;
}
修改为:
Array Array::printfInfo(){ // 修改printfInfo()函数的返回值为Array
cout << "len = " << len << endl;
return *this; // 返回this指针
}
由于函数printfInfo()返回了this指针,所以理论上语句 arr1.printfInfo().setLen(8) 相当于arr1.setLen(8) ,也就是该语句修改数据成员len为8,测试主函数如下:
int main(){
Array arr1(4);
arr1.printfInfo().setLen(8); //printfInfo()函数中返回了arr1对象的this指针,这里相当于arr1.setLen(8)
cout << arr1.getLen()<<endl; //检查上一条语句是否修改了数据成员len的值,运行结果发现len的值并没有改变, 为什么呢?
return 0;
}
运行结果(len修改不成功):
len = 4
4
- Q : 为什么语句arr1.printfInfo().setLen(8)并没有修改len的值?
- A : 这是因为printfInfo()函数是Array类型的,返回的this指针指向了一个新的Array对象(一个临时对象),而不是原来的对象arr1
- Q : 如果希望printfInfo()返回的this指针指向arr1 ,该怎么办呢?
- A : 在printfInfo()函数的返回类型后加引用,即Array& Array::printfInfo()
demo4.cpp源码
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo4.cpp this指针的特殊用法,修改成员函数 printfInfo()的返回类型,返回this指针
* *********************************************************/
class Array{
public:
Array(int len);
~Array();
void setLen(int x);
int getLen();
Array& printfInfo(); //修改printfInfo()函数的返回类型为Array,并加 &
private:
int len; //数据成员(Len)与成员函数的参数(len)重名
};
Array::Array(int len){
this->len = len; // this指针
}
Array::~Array(){
}
void Array::setLen(int len){
this->len = len; //this指针
}
int Array::getLen(){
return len;
}
Array& Array::printfInfo(){ // 修改printfInfo()函数的返回值为Array,并加 &
cout << "len = " << len << endl;
return *this; // 返回this指针
}
/****************** 测试主函数 ******************************/
int main(){
Array arr1(4);
arr1.printfInfo().setLen(8); //修改数据成员len
cout << arr1.getLen()<<endl; //检查上一条语句是否修改了数据成员len的值
system("pause");
return 0;
}
运行结果(len被成功修改):
len = 4
8
继续修改函数setLen():
Array& Array::setLen(int len){
this->len = len; //this指针
return *this;
}
测试主函数:
int main(){
Array arr1(4);
arr1.printfInfo().setLen(8).printfInfo(); //setLen()后面直接调用其他成员函数
//cout << arr1.getLen()<<endl; //不需要该语句了
return 0;
}
运行结果:
len = 4
len = 8
把引用修改为指针
demo6.cpp源码
#include<iostream>
#include<stdlib.h>
using namespace std;
/************************************************************
* demo6.cpp this指针的特殊用法 把引用修改为指针
* *********************************************************/
class Array{
public:
Array(int len);
~Array();
Array* setLen(int x); //函数的返回类型为Array ,并加指针
int getLen();
Array* printfInfo(); //函数的返回类型为Array ,并加指针
private:
int len; //数据成员(Len)与成员函数的参数(len)重名
};
Array::Array(int len){
this->len = len; // this指针
}
Array::~Array(){
}
Array* Array::setLen(int len){
this->len = len; //this指针
return this;
}
int Array::getLen(){
return len;
}
Array* Array::printfInfo(){ // 修改printfInfo()函数的返回值为Array,并加指针
cout << "len = " << len << endl;
return this; // 返回this指针,这里不需要星号了
}
/****************** 测试主函数 ******************************/
int main(){
Array arr1(4);
//arr1.printfInfo().setLen(8).printfInfo();
arr1.printfInfo()->setLen(8)->printfInfo(); //改成指针的调用方式
system("pause");
return 0;
}
运行结果
len = 4
len = 8