this指针的那些事儿

1.this指针(自引用指针)的概念引入

       当定义了类的若干对象之后,系统会为每一个对象分配存储空间。如果一个类包含了成员函数和数据成员,就要分别为数据和函数的代码分配存储空间。 

       

       事实上,给对象赋值就是给对象的成员数据赋值,不同对象的存储单元中存放的数据值通常是不相同的,而不同对象的函数代码是相同的,无论调用哪一个对象的成员函数,其实调用的都是相同的代码。


       C++的编译系统只用了一段空间来存放这个共同的函数代码段,在调用各个对象的成员函数时,都会去调用这个公用的函数代码段(这也是为什么类的大小不包括成员函数的原因)。


       因此,每个对象的存储空间都只是该对象的数据成员所占的存储空间,而不包括成员函数代码所占的空间,函数代码是存储在对象之外的。


      既然如此,每个对象都有自己的数据成员,但是对象的成员函数代码却合用一份。那么成员函数是怎样辨别出当前调用自己的是哪个对象,从而对该对象的数据成员而不是其他对象的数据成员进行处理呢?


      就好比当我们进入一个房子之后,可以看见里面的桌子,椅子,地板等,但却看不到房子的全貌。对于一个实例而言,你可以看到该实例的数据成员和成员函数,但是实例本身我们是看不到的,而this指针时时刻刻指向这个实例。this指针的值是当前调用成员函数的对象的起始地址。


2.this指针的特性

<1>this指针的类型:类类型  *const

验证代码:

#include<iostream>
using namespace std;

class A
{
public:
	void test(int y);
private:
	int x;
};

void A::test(int y)
{
	this = y;
	cout<<y<<endl;
}
void Funtest()
{
	A a;
	a.test(4);
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}
运行结果:



<2>this指针本身并不是对象的一部分,所以不会影响sizeof的结果。

#include<iostream>
using namespace std;

class A
{
public:
	void test();
private:
	int x;
	int y;
	int z;
};

void A::test()
{
	int n = sizeof(A);
	cout<<n<<endl;
}

void Funtest()
{
	A a;
	a.test();
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}
运行结果:



<3>this指针的作用域在非静态数的内部。

#include<iostream>
using namespace std;

class A
{
public:
	void test();
private:
	int x;
};

void A::test()
{
	cout<<this<<endl;
}

void Funtest()
{
	A a;
	a.test();
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}


<4>this指针是类成员函数的第一个默认隐含参数。

验证代码:

#include<iostream>
using namespace std;

class A
{
public:
	void test(int y);
private:
	int x;
};

void A::test(int y)
{
	this->x = y;
	cout<<y<<endl;
}
void Funtest()
{
	A a;
	a.test(4);
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}



运行结果:


<5>当数据成员名与成员函数的参数名相同时,必须显示调用this指针。

#include<iostream>
using namespace std;

class A
{
public:
	void test(int x);
private:
	int x;
};

void A::test(int x)
{
	x = x;//错误,形参自己给自己赋值
	this->x = x;//正确,将形参x的值赋值给当前对象的成员数据x
	cout<<x<<endl;
}
void Funtest()
{
	A a;
	a.test(4);
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}

<6>this指针是系统自定义的,用户不必再重复定义。


<7>只有在非静态成员函数内部才能使用this指针,因为静态成员函数没有this指针。

#include<iostream>
using namespace std;

class A
{
public:
	void test();
	static void test1();
private:
	int x;
};

void A::test()
{
	cout<<this<<endl;
}
void test1()
{
	cout<<this<<endl;
}

void Funtest()
{
	A a;
	a.test();
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}
错误提示:



<8>this指针是可以为空的。

#include<iostream>
using namespace std;

class A
{
public:
	void test();
private:
	int x;
};

void A::test()
{
	cout<<this<<endl;
}

void Funtest()
{
	A *a = NULL;
	a->test();
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}
打印结果:



3.非静态成员函数的调用约定:_thiscall

<1>_thiscall只能用在类的非静态成员函数上。

<2>参数从右向左压栈。

<3>如果参数个数确定,this指针通过ecx传递给被调用者,如果参数不确定,this指针在所有参数压栈之后被压入堆栈。

<4>对于参数个数不确定的,调用者清理堆栈,否则函数自己清理堆栈。


4.为什么叫this指针而不是引用?

 答:因为this指针存放当前正在调用对象的地址,而引用则是某个对象的别名,和该对象占同一块空间地址,二者区别还是蛮大的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值