1. this指针初识
class A {
public:
void Set(int a, int b) { // 设置类中的成员变量
_a = a;
_b = b;
}
void display() { // 显示 display(A* const this)
cout << _a << "-" << _b << endl;
}
private:
int _a;
int _b;
};
int main() {
A a1;
a1.Set(10, 20);
A a2;
a2.Set(100, 200);
a1.display(); // this->&a1
a2.display(); // this->&a2
system("pause");
return 0;
}
为什么在调用display做显示的时候,根本就没有对其进行传参,打印结果却不同呢?虽然对象不一样,并且没有传参,但是实际上背后是this指针在发挥着作用。虽然看着没有传参,但是编译器会帮着你传参,传的这个参数就是this指针,并且每个this指针都不一样,它指向当前调用函数对象的进程,而且这个this指针它是这个成员函数的第一个形参,并且这个形参不需要显式的去创建,编译器在底层会对成员函数进行处理为display(A* const this),这个指针在内部是不能变的。
虽然看着函数体中没有关于不同对象的区分,那么如何进行有序的调用呢?C++中通过引入this指针解决该问题,即:C++编译器给每个“成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
2. this指针的特性
1)this指针的类型:类类型* const
2)只能在“成员函数”的内部使用
3)this指针本质上其实是一个成员函数的形参(不论任何时候,成员函数的第一个形参总是this指针),是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
4)this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递(一般是放在栈上,通过优化通过ecx寄存器上),不需要用户传递。
3. 常见面试题
1)this指针存在哪里?
一般是放在栈上,通过优化通过ecx寄存器上,通过优化编译器通过ecx寄存器自动传递。CPU一般有8个寄存器,有存栈帧、有存临时变量的,目的是为了高效访问。
2)this指针可以为空吗?
class A {
public:
void Set(int a, int b) { // 设置类中的成员变量
_a = a;
_b = b;
}
void display() { // 显示
cout <<this-> _a << "-" << this->_b << endl; // this指针解引用
}
void fun() { // 传入this指针但并没有使用,即便为空也没有问题
cout << "fun()" << endl;
}
private:
int _a;
int _b;
};
int main() {
A* pa = nullptr;
pa->display(); // 程序崩溃
pa->fun(); // 程序正常结束
system("pause");
return 0;
}
只要this指针在成员函数中没有进行解引用的操作,this指针可以为空。但是若进行this指针为空指针并解引用,肯定会引发错误。