this指针

来源:互联网 发布:苹果越狱网络不可用 编辑:程序博客网 时间:2024/04/29 20:56

----------------siwuxie095

  

  

  

  

  

  

  

  

  

this 指针

  

  

看如下实例:

  

定义一个Array 类,数据成员为:len

  

  

  

  

通过观察,可以发现:参数和数据成员并不同名

  

  

  

  

看如下实例:

  

  

  

如果同名,有如下问题:

构造函数中,如果这样写,不管是人类还是计算机,都无法判断究竟是

将参数赋值给数据成员了,还是将数据成员赋值给参数了

  

setLen() 函数中同理 …

  

既然计算机无法判断,就会把这样的赋值认为是错误的

  

可见:主要问题在于编译器无法分辨哪个是作为参数的len,

哪个是作为数据成员的len

  

这就是说,迫切的需要一种技术,这种技术要么可以标记出

参数,要么可以标记出数据成员,这种技术正是this 指针

  

  

  

this 指针,即 指向对象自身数据的指针

  

如果使用Array 类实例化一个对象 arr1,this 指针就相当于是给 arr1 取地址,

即 this 是 arr1 的地址,如果再实例化一个对象arr2,那么 this 指针此时就是

arr2 的地址

  

  

  

  

在内存空间中的表示:

  

  

  

this 如果写在 arr1 中,就是 arr1 的地址,如果写在 arr2 中,就是 arr2 的地址

  

可见:this 要表达什么意思取决于它放在什么位置,通过 this 指针可以访问到它

表达的对象自身的任何数据

  

  

  

从另一个角度来说,就可以标记出它自身的数据成员,应用到

代码中就可以写成这样:

  

「参数和数据成员同名时,计算机就不会再疑惑,也能够正常的编译通过」

  

  

  

  

继续观察之前的例子,难道大家没有对成员函数中直接去访问数据成员

这种做法产生过怀疑吗?

  

  

  

  

  

  

回顾对象结构的实例:

  

car1、car2、car3 都有自己的数据成员,但成员函数却只有一份,

这份成员函数写在代码区,三个对象都可以各自访问代码区中的成

员函数,而且访问时也不会出任何的问题,在成员函数被调用的时

候,也各自调用到了每一个对象的数据成员,并且没有出现混乱

  

  

  

  

那么问题来了:既然函数的逻辑代码都是以二进制的形式存储在代

码区,参数中也没有数据成员,那么在调用数据成员,尤其是存在

多个对象时,函数如何确定该调用哪个对象的数据成员呢?

  

  

  

  

要解决这个问题,也归功于this 指针,看如下实例:

  

  

  

不难发现,每一个成员函数的参数列表中都多出了一个this 指针,而

有了这样一个this 指针,前面的问题也就迎刃而解了

  

  

  

我们可以设想一下,当实例化对象并使用这些成员函数时,this 指针

就代表着这个对象本身的地址

  

  

当实例化arr1 时,构造函数中传入参数 this,当执行给 len 赋值

10 的操作时,相当于是在执行this 的 len 赋值 10 的操作,因为

this 就指的是 arr1,所以用 this 指向 len 时,其实指向的是 arr1

的 len,也就不会给其他的对象赋错值了

  

同理,如果用arr1 调用 getLen() 时,也传入了参数 this,当调用

return len 时,相当于调用 return this->len,也就是 arr1 的 len

  

当实例化 arr2 时,此时的 this 就已经是 arr2 的地址了 …

  

从而使 arr1 和 arr2 在同时调用这些成员函数时,不会产生对象错

乱的情况

  

  

  

因为每次调用成员函数,都需要this 指针,所以 C++ 的编译器

干脆就替我们干了这件事,于是摆在我们面前的成员函数就成了

现在的样子:不加this

  

  

  

  

其实在编译时,编译器自动的为每一个成员函数的参数列表都加了

一个 this 指针

  

因为编译器为我们干了这些事情,所以自定义时就不必要再加this

指针这个参数,使用的时候也完全可以当做没这回事儿

  

  

  

  

  

  

程序 1

  

Array.h:

  

class Array

{

public:

Array(int len);

~Array();

void setLen(int len);

int getLen();

void printInfo();

private:

int len;

};

  

  

  

Array.cpp:

  

#include"Array.h"

  

Array::Array(int len)

{

//容易混淆的地方用this指针标记(不标记的话编译器就不知道

//是参数给数据成员赋值还是数据成员给参数赋值)

this->len = len;

}

  

Array::~Array()

{

  

}

  

void Array::setLen(int len)

{

this->len = len;

}

  

int Array::getLen()

{

return len;

}

  

void Array::printInfo()

{

  

}

  

  

  

main.cpp:

  

#include <stdlib.h>

#include"Array.h"

#include <iostream>

using namespace std;

  

  

int main(void)

{

Array arr1(5);

cout << arr1.getLen() << endl;

system("pause");

return0;

}

  

  

  

  

  

  

程序 2:

  

Array.h:

  

class Array

{

public:

Array(int len);

~Array();

Array* setLen(int len);

int getLen();

Array& printInfo();

private:

int len;

};

  

  

  

Array.cpp:

  

#include"Array.h"

#include <iostream>

using namespace std;

  

  

Array::Array(int len)

{

//在容易混淆的地方用this指针标记

this->len = len;

}

  

Array::~Array()

{

  

}

  

Array* Array::setLen(int len)

{

this->len = len;

//return出去的是arr1this指针

return this;

}

  

int Array::getLen()

{

return len;

}

  

Array& Array::printInfo()

{

  

cout <<"len=" << len << endl;

return *this;//return出去的是arr1的引用

}

  

//Array Array::printInfo()

//{

//

// cout << "len=" << len << endl;

// return *this;//return出去的是新的临时对象

//}

  

  

  

main.cpp:

  

#include <stdlib.h>

#include"Array.h"

using namespace std;

  

//this指针的本质就是其所在对象的地址

int main(void)

{

Array arr1(10);

//根据返回值类型的不同选择不同的操作符 . ->

arr1.printInfo().setLen(5)->printInfo();

system("pause");

return0;

}

  

//printInfo()前面是Array&setLen(5)

//

//arr1.printInfo().setLen(5);

//arr1.printInfo();

//

//最终打印出一个10一个5

  

//如果printInfo()前面不是Array&而是Array

//那么return出来的就是一个新的临时对象(是另外的对象,并不是arr1)

//setLen(5)

//

//arr1.printInfo().setLen(5);

//arr1.printInfo();

//

//就会打印出两个10而不是一个10一个5

  

//Array& Array*效果一样只不过一个是指针一个是引用罢了

//这便是Array Array& Array* 的不同与妙用了

  

//假如我在printInfo()函数中把原来的cout换成 cout<<this<<endl;

//即打印出this指针的地址同时在main()函数中 cout<<&arr1<<endl;

//这样就可以清晰的看到this指针指向的是对象的地址(this指针的本质)

  

  

  

  

  

  

  

  

  

【made by siwuxie095】

0 0
原创粉丝点击