c++学习-this指针

1.基本概念

非静态成员函数都会默认传递this指针(静态成员函数属于类本身,不属于某个实例对象),方便访问对象对类成员变量和 成员函数。

2.基本使用

编译器实际处理类成员函数,this是第一个隐藏的参数,类型为指向当前对象的指针

cpp 复制代码
void func();             // 表面形式
void func(MyClass* this);  // 实际内部形式

编辑代码

cpp 复制代码
class MyClass {
public:
    int a;
    void show() {
        std::cout << a << std::endl; // 相当于 std::cout << this->a;
    }
};

编译器处理

cpp 复制代码
void show(MyClass* this) {
    std::cout << this->a << std::endl;
}

2.1区分参数和类成员变量

类成员函数中变量/函数查找顺序:①当前作用域->②函数参数->③类成员变量/函数(通过this指针查找)->④父类成员->⑤编译器报错。

通过this指针可以区分类成员变量还是传入参数

cpp 复制代码
#include <iostream>

using namespace std;

class Persion {
public:
	void SetAge(int age) {
		this->age = age; // this指针指向调用成员函数的对象本身
	}
	void SetHeight(double height) {
		height = height; // 优先使用局部变量height,未使用this指针
	}
	void ShowAge() {
		cout << "Age: " << age << endl; // 使用this指针访问成员变量
	}	
	void ShowHeight() {
		cout << "Height: " << height << endl; // 使用this指针访问成员变量
	}

	int age = 0;
	double height = 0;
};

int main() {
	Persion p;
	p.SetAge(25);
	p.SetHeight(175.5);
	p.ShowAge();    // 输出: Age: 25
	p.ShowHeight(); // 输出: Height: 0
	return 0;
}

ShowAge方法中,先查找函数作用域没有age变量,通过隐藏this指针查找到类成员变量age

2.2链式调用

通过返回this可以实现链式调用

cpp 复制代码
#include <iostream>

using namespace std;

class Persion {
public:
	//需要使用返回Person的引用的方式,才能实现链式调用,否则会重新创建一个对象
	Persion& SetAge(int age) {
		this->age = age; // this指针指向调用成员函数的对象本身
		return *this; // 返回对象本身的引用
	}
	Persion& SetHeight(double height) {
		this->height = height; // 优先使用局部变量height,未使用this指针
		return *this; // 返回对象本身的引用
	}
	void ShowAge() {
		cout << "Age: " << age << endl; // 使用this指针访问成员变量
	}	
	void ShowHeight() {
		cout << "Height: " << height << endl; // 使用this指针访问成员变量
	}

	int age = 0;
	double height = 0;
};

int main() {
	Persion p;
	p.SetAge(25).SetHeight(175.5);
	p.ShowAge();    // 输出: Age: 25
	p.ShowHeight(); // 输出: Height: 175.5
	return 0;
}

3.问题

1.非静态类成员函数中使用的this是类成员变量还是编译器隐式传递的this参数

this指针不是一个类成员变量 ,类成员函数中使用的this指针是编译器隐式传递的this参数。 (这就是为什么静态成员函数里不能使用类成员变量和类成员函数,因为静态成员函数没有this指针参数,在函数内部就无法通过this指针找到对应的实例对象的成员变量以及成员函数)

cpp 复制代码
#include <iostream>

using namespace std;

class Persion {
	//this指针是隐含在所有非静态成员函数中的一个指针,指向调用该成员函数的对象,编译器会自动传递this指针
	//this指针不是类成员变量
public:
	//非静态成员函数编译器会自动传递this指针
	void setAge(int a) {
		this->age = a;//通过this指针访问成员变量
	}
	//静态成员函数编译器不会自动传递this指针
	static void getAge() {
		cout << "age is " << this->age << endl;//报错,静态成员函数没有this指针
	}
	int age;
};

int main() {
	Persion p;
	return 0;
}

2.什么情况自动获取this指针并传递给类成员函数,什么时候需要手动传递?

编译器自动传递this指针:在非静态成员函数内部调用类成员函数和类成员变量时(非静态成员函数本身有隐藏this指针参数)或则通过对象直接调用非静态成员函数时(编译器会根据对象自动生成指向该对象的指针),this指针会被编译器自动传递。

需要手动传递this指针:当将静态成员函数"脱离对象上下文"传递(如给线程或lambda表达式,必须手动指定this。

cpp 复制代码
#include <iostream>
#include <thread>

using namespace std;

class Persion {
public:
	//需要使用返回Person的引用的方式,才能实现链式调用,否则会重新创建一个对象
	Persion& SetAge(int age) {
		this->age = age; // this指针指向调用成员函数的对象本身
		return *this; // 返回对象本身的引用
	}
	Persion& SetHeight(double height) {
		this->height = height; // 优先使用局部变量height,未使用this指针
		return *this; // 返回对象本身的引用
	}
	void ShowAge() {
		cout << "Age: " << age << endl; // 使用this指针访问成员变量
	}	
	void ShowHeight() {
		cout << "Height: " << height << endl; // 使用this指针访问成员变量
	}
	void testThisPoint() {
		std::thread t1(&Persion::ShowAge, this); // 传递this指针,必须显示传递类成员函数ShowAge第一个参数this
		std::thread t2([this]() { ShowHeight(); }); // 使用lambda表达式捕获this指针,表示式作用域内找不到ShowHeight方法,再通过this指针访问
		t1.join();
		t2.join();
		std::cout << t1.joinable() << std::endl;
		std::cout << t2.joinable() << std::endl;
	}


	int age = 0;
	double height = 0;
};

int main() {
	Persion p;
	p.SetAge(25).SetHeight(175.5);
	p.testThisPoint();
	return 0;
}

3.成员函数如何区分使用变量是类成员变量还是未定义变量或则传入参数变量?this指针工作原理

层层查找,和普通变量作用域一样,从内到外层层查找

①当前作用域->②函数参数->③类成员变量/函数(通过this指针查找)->④父类成员->⑤编译器报错。

4.总结

1.this指针不是一个类成员变量 ,类成员函数中使用的this指针是编译器隐式传递的this参数。

相关推荐
_君落羽_2 分钟前
Linux操作系统——TCP服务端并发模型
linux·服务器·c++
望获linux2 小时前
【Linux基础知识系列】第一百一十篇 - 使用Nmap进行网络安全扫描
java·linux·开发语言·前端·数据库·信息可视化·php
Q741_1474 小时前
C++ 力扣 76.最小覆盖子串 题解 优选算法 滑动窗口 每日一题
c++·算法·leetcode·双指针·滑动窗口
雷达学弱狗5 小时前
链式法则解释上游梯度应用
开发语言·前端·javascript
爱隐身的官人6 小时前
爬虫基础学习-爬取网页项目(二)
前端·爬虫·python·学习
Ysn07198 小时前
pytorch_grad_cam 库学习笔记—— Ablation-CAM 算法的基类 AblationCAM 和 AblationLayer
pytorch·笔记·学习
小清兔8 小时前
c#基础知识
开发语言·数据库·学习·unity·c#·游戏引擎·.net
霜绛8 小时前
Unity笔记(七)——四元数、延迟函数、协同程序
笔记·学习·unity·游戏引擎
2006yu9 小时前
从零开始学习单片机13
单片机·嵌入式硬件·学习
风和日丽 随波逐流9 小时前
java18学习笔记
笔记·学习·java18