在上一篇博文中,对C++This指针的本质详细地讲解了,这篇博文主要是讲C++This指针的用法,应用场景等。
最简单的应用场景就是:当我们在类中定义了一个变量,同时在类成员函数中定义了同一变量时,也就是说变量名重复时,但是我们想使用类中定义的变量,这个时候我们该怎么办呢?这个时候就是this指针大显身手的时候了。为此我们引入this指针的概念。
一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是在类内部(非静态成员函数),当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。
例如,调用date.SetMonth(9) <===>类型::SetMonth(&date, 9)。
对象调用成员函数,想返回对象本身,可以使用如下语法
return *this
可能有的人会疑惑,为什么要返回对象本身?
返回对象本身的好处是可以进行链式调用函数,也很简便。
this->n = n (不能写成n = n)
#include
#include
using namespace std;
class Point
{int x, y;
public:
Point(int a, int b) { x=a; y=b;}
void MovePoint( int a, int b){ x+=a; y+=b;}
void print(){ cout << "x=" << endl};
void main( )
{
Point point1( 10,10);
point1.MovePoint(2,2);
point1.print( );
}
this指针存在于类的成员函数中,指向被调用函数所在的类实例的地址。
当对象point1调用MovePoint(2,2)函数时,即将point1对象的地址传递给了this指针。
MovePoint函数的原型应该是 void MovePoint( Point * const this, int a, int b);第一个参数是指向该类对象的一个指针,我们在定义成员函数时没看见是因为这个参数在类中是隐含的。这样point1的地址传递给了this,所以在MovePoint函数中便显式的写成:
void MovePoint(int a, int b) { this->x +=a; this-> y+= b;} 即可以知道,point1调用该函数后,也就是point1的数据成员被调用并更新了值。 即该函数过程可写成 point1.x+= a; point1. y + = b;
全局函数、静态函数都不能使用this.
实际上,成员函数默认第一个参数为T * const this。
如:
class A
{
public:
int func(int p)
{
}
};
其中,func的原型在编译器看来应该是:
int func(A * const this,int p);
这个生命周期同任何一个函数的参数是一样的,没有任何区别。
当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去。如:
A a;
a.func(10);
此处,编译器将会编译成:
A::func(&a,10);
this指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局区。在汇编级别里面,一个值只会以3种形式出现:立即数、寄存器值和内存变量值。不是存放在寄存器就是存放在内存中,它们并不是和高级语言变量对应的。
This指针变量和其他变量不一样,函数形参都是创建于栈上
而大多数编译器通过ecx寄存器传递this指针。
注意:编译器是在创建对象的时候,向ecx寄存器传递This指针
#include
#include
using namespace std;
class CTest
{
public:
void SetValue();
int m_iValue1;
int m_iValue2;
};
void CTest::SetValue()
{
m_iValue1 = 13;
m_iValue2 = 13;
}
int main()
{
CTest test;
test.SetValue();
return 0;
}
我们看下这个例程的汇编代码:
在创建test对象的时候,就是将test的地址传给了ecx。
This指针的作用域只在成员函数中,所以在类外是不能够出现This指针。
#include
#include
using namespace std;
class CTest
{
public:
void SetValue();
int m_iValue1;
int m_iValue2;
};
void CTest::SetValue()
{
this->m_iValue1 = 13; //通过指针引用
this->m_iValue2 = 13; //通过指针引用
}
int main()
{
CTest test;
test.SetValue();
return 0;
}
#include
#include
using namespace std;
class CTest
{
public:
void SetValue();
int m_iValue1;
int m_iValue2;
};
void CTest::SetValue()
{
m_iValue1 = 10;
m_iValue2 = 13;
}
int main()
{
CTest test;
CTest* ptest = &test;
ptest->SetValue(); //通过指针的方式调用
return 0;
}
using namespace std;
class CTest
{
public:
void SetValue();
int m_iValue1;
int m_iValue2;
};
void CTest::SetValue()
{
m_iValue1 = 10;
m_iValue2 = 13;
}
int main()
{
CTest test;
test.SetValue();//通过对象进行调用
return 0;
}
本片博文主要是讲了C++This指针的用法,学了这篇文章后,你应该能够掌握This指针的用法。C++This指针是比较难但又是很重要的。自己在汇编层面还是比较欠缺,所以学好C++和C,就得学好计算机底层,就得学好汇编!
加油吧,路在脚下!