【带你一次性读懂C++之this指针】

news/2024/7/5 4:31:16

系列文章目录

        欢迎大家订阅我的《计算机底层原理》、《自定向下看Java》、《深度解析C++》系列专栏,我会为大家持续输出优质文章,能够帮助到大家就是对我最大的鼓励。


目录

系列文章目录

前言

一、为什么需要this指针

二、this指针的使用

        1.访问成员变量

        2.调用其它成员函数

三、this指针的隐式传递

四、this指针和const成员函数

总结


前言

        


一、为什么需要this指针

       this指针是C++当中用于指向当前对象的指针,它是成员函数内的一个隐式参数,指向调用该成员函数的对象的内存地址(this指针存放的内容就是对象的内存地址),this指针的主要用途是在成员函数内部访问对象的成员变量和调用其他的成员函数。

        在类的成员函数当中,如果存在与类的成员变量同名的局部变量或者函数参数,编译器可能无法区分它们,这个时候我们就需要使用this指针可以明确地指出成员变量属于当前对象。

        例如像遇到这样的情况的时候,类的成员变量和构造函数当中的参数发生了冲突,那么这个时候就会需要this指针进行区分。其实想要避免这样的问题出现的话也有一个办法,就是不要让成员变量和函数的参数同名,具体怎么做取决于程序员的个人喜好。

class MyClass {
public:
    int x;

    void setX(int x) {
        // 使用 this 指针访问成员变量
        this->x = x;
        //x = x;如果直接这么写的话编译器会发生混淆
    }
};

二、this指针的使用

        1.访问成员变量

        我们使用this指针就可以在成员函数体内访问对象的成员变量。

class MyClass{
public:
    int x;
public:
    void Print(){ cout << this -> x << endl;}
}

        2.调用其它成员函数

        使用this指针可以在成员函数当中调用其它成员函数。这里其实是不是用this指针调用都可以在同一个类当中我们可以直接调用其它同类的成员函数,编译器可以自动识别,只不过这里使用this指针会更加地清晰明确。

class Animal {
public :
	int age;
	string name;
	
public:
	Animal(int age, string name) {
		this->age = age;
		this->name = name;
	}
	void Func() {
		this->Print();
	}
	void Print() {
		cout << "Hello World!" << endl;
	}
};


三、this指针的隐式传递

        当我们在调用对象的成员函数的时候,编译器会在幕后自动地将对象的地址传递给this指针,这个过程是隐式的,程序员不需要显示地传递this指针,this指针是我们类当中的每一个非静态的成员函数的第一个隐式的参数。this指针的类型就是类的类型的指针,而且是const(注意这里的const修饰的是指针,也就意味着我们不能修改this指针的值,他只能指向对象本身。)

class MyClass {
public:
    int x;

    void setX(MyClass* const this,int x) {
        // 使用 this 指针访问成员变量
        this->x = x;
        //x = x;如果直接这么写的话编译器会发生混淆
    }
};

        这里的参数是隐式的,这一步我们程序员不需要知道,而是由编译器来为我们负责,接下来我为大家详细地解释一下对于隐式的传参编译器都做了什么。代码如下:

MyClass obj;
obj.setX(42); // 编译器将 &obj 传递给 this 指针

        1.识别对象地址:

        编译器知道obj是一个MyClass类型的对象,因此能够识别到obj的地址,也就是&obj。

        2.隐式传递this指针:
        当我们调用setX函数的时候,编译器会在幕后将&obj传递给this指针,实际上调用setX的底层机制是类似于这样的。

obj.setX(&obj,42);

        我们的成员函数之所以能够调用我们的成员变量并且对他们进行操作就是因为我们有this指针,我们不管是在成员函数内部是调用成员变量还是在一个成员函数内部调用另外一个成员函数都是依靠this指针。

        不过到了这里可能会有小伙伴要问了你刚才不是说了调用成员变量和成员函数不需要this指针显式调用也可以吗,怎么现在又说我们不管是在成员函数内部是调用成员变量还是在一个成员函数内部调用另外一个成员函数都是依靠this指针呢?其实很简单,因为编译器帮我们做了优化,即使我们程序员自己不调用this指针,编译器也会替我们隐式地调用,只不过这一步对我们是透明的,我们看不到罢了。

        就这样编译器通过隐式传递this指针,成员函数内部能够在执行时准确地操作调用它的对象成员变量,这也就是为什么可以在成员函数内部直接使用成员变量而不需要指定对象的原因,因为this指针指向当前对象。


四、this指针和const成员函数

         在常量成员函数当中,this指针就会被修饰称为const MyClass* const this,注意了这两个const关键字位置不一样用法可是天差地别,第一个const修饰的是类型,代表这个指针存储的值必须是常量也就是这个指针只能访问常量,第二个const修饰的是指针,就意味着这个指针本身一个是常量,也就意味着这个指针不能够被修改,他只能指向对象的内存地址,如果想把this指针赋值给别人是不可以的。例如

class MyClass {
public:
    int x;

    void constFunction() const {
        // this 指针的类型是 const MyClass*
        // 不能修改成员变量 x
        int value = this->x; // 合法
        // this->x = 42; // 不合法
    }
};

       这里的成员函数末尾加上const就意味着this指针指向的内容必须是一个常量,而x变量不是常量所以不能修饰。因为我们只能读取常量变量,但是不能对其进行修改。

        这样设计的目的是为了确保常量成员函数不会意外地修改对象的状态,如果不加上这里的const的话,意味着成员函数可以利用this指针随意地修改对象的成员变量,会引发很多意外的操作,这么做也是为了使得它们能够被安全地用于处理对象,总之通过在成员函数声明中加上const关键字,this指针的类型被限制为指向常量的指针,从而确保在常量成员函数当中只能访问而不能修改对象。


        拓展:

        这里我拓展一下,this指针属于对象内存布局当中的一个成员,如果一个对象在栈当中开辟空间那么就意味着这个this指针存储在栈上,如果这个对象利用new关键字在堆上开辟空间,那么这个this指针就在堆上存储,总之这个this指针是属于对象的,对象在哪里this指针就在哪里,这里要和Java进行区分,Java当中的对象一定在堆上,但是this指针却存放在虚拟机栈当中的局部变量表当中,所以大家这里要做好区分,语言之间不要相互混淆。


总结

        今天我为大家详细地介绍了,this指针的相关用法以及特性,this指针是我们理解C++语言非常重要的基础,之后我们会频繁地使用这个概念,希望我的这篇文章能够解答小伙伴们心目当中关于this指针的疑惑。


http://lihuaxi.xjx100.cn/news/1907407.html

相关文章

Actuator内存泄露及利用Swagger未授权自动化测试实现

目录 0x00 前言 0x01 Actuator 泄露及利用 1、Actuator heapdump 内存泄露 2、知道泄露后如何进一步利用 3、如何发现 Actuator 泄露&#xff08;白盒/黑盒&#xff09; 0x02 Swagger自动化测试 1、什么是Swagger&#xff1f; 2、PostmanBurpSuiteXray 联动 3、思考 0x…

ip静态好还是dhcp好?

选择使用静态 IP 还是 DHCP&#xff08;动态主机配置协议&#xff09;取决于您的网络需求和环境。下面是它们的一些特点和适用场景&#xff1a; 静态 IP&#xff1a; 固定的 IP 地址&#xff1a;静态 IP 是手动配置在设备上的固定 IP 地址&#xff0c;不会随时间或网络变化而改…

TCP_滑动窗口介绍

简介 TCP协议中有两个窗口&#xff0c;滑动窗口和拥塞窗口&#xff0c;两者均是一种流控机制&#xff1b;滑动窗口是接收方的流控机制&#xff0c;拥塞窗口是发送方的流控机制。 本文介绍滑动窗口&#xff0c;接收方为TCP连接设置了接收缓存。当TCP连接接收到正确、按序的字节…

网络技术基础与计算思维实验教程_3.1_单BSS实验(基本服务集合实验)

无线局域网的最小基本组件是基本服务BSS 实验内容 实验目的 实验原理 实验步骤 为了显示AP的有效通信范围 切换到物理工作区 把物理工作区导航到城市家园 直接在城市家园放置AP0 可以看到AP0的通信范围 放置笔记本电脑 在默认情况下 笔记本电脑上 安装了以太网卡 现在换成无…

使用阿里云性能测试工具 JMeter 场景压测 RocketMQ 最佳实践

作者&#xff1a;森元 需求背景 新业务上线前&#xff0c;我们通常需要对系统的不同中间件进行压测&#xff0c;找到当前配置下中间件承受流量的上限&#xff0c;从而确定上游链路的限流规则&#xff0c;保护系统不因突发流量而崩溃。阿里云 PTS 的 JMeter 压测可以支持用户上…

【MATLAB第84期】基于MATLAB的波形叠加极限学习机SW-ELM代理模型的sobol全局敏感性分析法应用

【MATLAB第84期】基于MATLAB的波形叠加极限学习机SW-ELM代理模型的sobol全局敏感性分析法应用 前言 跟往期sobol区别&#xff1a; 1.sobol计算依赖于验证集样本&#xff0c;无需定义变量上下限。 2.SW-ELM自带激活函数&#xff0c;计算具有phi&#xff08;x&#xff09;e^x激…

(自适应手机版)英文外贸网站模板 - 带三级子目录

(自适应手机版)英文外贸网站模板 - 带三级子目录 PbootCMS内核开发的网站模板&#xff0c;该模板适用于外贸网站、英文网站类等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b; 自适应手机版&#xff0c;同一个后台&#x…

TikTok获客工具定制开发怎么做?

随着社交媒体的兴起&#xff0c;越来越多的企业开始把目光投向了海外市场&#xff0c;而在这个数字化时代&#xff0c;TikTok已经成为了一个备受欢迎的短视频平台&#xff0c;不仅吸引了大量的年轻用户&#xff0c;也成为了许多企业的新宠。 但是&#xff0c;如何在TikTok上获…