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出去的是arr1的this指针
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】
- this指针
- this指针
- this指针
- this指针
- this指针
- this 指针
- this指针
- this指针----
- this指针
- this 指针
- This 指针
- this指针
- This指针
- this指针
- this指针
- this 指针
- this指针
- this指针
- OpenCV离散余弦变换原理与源码
- 小白入门,OSI七层模型图解
- 苹果的短片制作应用即将在 App Store 上架
- 《Cracking the Coding Interview程序员面试金典》----猫狗收容所
- html5有哪些新特性?
- this指针
- Angular开发系列教程
- 秒杀系统架构分析与实战
- angular -$http登录功能
- 开启关闭去电监听
- web.js.什么时候使用“.”或者“[]”
- Android电源管理框架
- Angular开发(二)-关于angular2的整体架构与大致介绍
- Abbott's Revenge UVA