this指针详细总结 | static关键字 | 静态成员

文章目录

        • 1.this指针引入
        • 2.this指针的特性
        • 3.静态成员
          • 3.1.C语言中static的基本用法
          • 3.2.C++中的static关键字

1.this指针引入
class student
{
public:
	student(const string& name){	
		_name = name;	
	}
	void print(){
        // _name<=>this->_name<=>(*this)._name
        // 说一下:指针用箭头->返回成员(如:结构体,this->_name); 对像用.来访问成员
		cout << "我是" << _name << endl; 
	}
private:
	string _name;
};
int main()
{
	student stu1("张三");	stu1.print();
	student	stu2("李四");	stu2.print();

	return 0;
}

结果输出:

我是张三
我是李四

C++编译器为每个"非静态的成员函数",增加了一个隐藏的this指针,然该指针指向当前对象(函数运行时调用该函数的对象),来完成对"成员变量"的操作! 输出张三,说明访问stu1对象中村存储的数据"张三";数据李四,方式的是stu2对象域中的数据,根据this指针代表的对象不同,访问到的数据就会不同。

2.this指针的特性

this指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参; this在成员函数开始执行前构造,在执行结束后销毁。那this指针存放在哪里?

class number
{
public:
	void sum(int x, int y){
		_result = x + y;
	}
private:
	int _result = 0;
};

int main()
{
	number num;
	num.sum(1, 2);
	return 0;
}

在32位机器上,通过上面的代码对num.sum(1, 2);反汇编:

	num.sum(1, 2);
00671907  push        2  
00671909  push        1  
0067190B  lea         ecx,[num]  
0067190E  call        number::sum (06712F3h) 

可以看的,在call调用sum成员函数之前编译器ecx计数寄存器自动传递this指针;一般来说this指针是在栈上的,VS将对象的num的地址存放到ecx中!this指针存放到ecx中;不同的编译器可能会有不同。

this指针是:类的类型 * const 所以在成员函数中不能对this指针做修改

class number
{
public:
	void sum(int x, int y){
		this = nullptr;	// 不允许,也不允许&this(想要查看this的地址)
		_result = x + y;
	}
private:
	int _result = 0;
};

另外,this指针是编译器自动的传递,而且会占用参数的第一个位置,我们不用显示的传递,也不能在成员函数中显示的接收,但是在成员函数中显示的使用 如:this->_result

class number
{
public:
	void sum(number const& this,int x, int y){
		_result = x + y;
	}
private:
	int _result = 0;
};

当然我们可以使用this来区分两种定义对象的不同方式:

class student
{
public:
	student(const string& name) {
		_name = name;
	}
	void print() {
		int num = 1;
		char* ptr = (char*)malloc(1);
		printf("num的地址:%p,malloc的地址:%p,this指向对象的地址:%p\n", &num,ptr,this);
		cout << "我是" << _name << endl;
	}
private:
	string _name;
};
int main()
{
	student stu1("张三");	
	stu1.print();
	student* stu2 = new student("李四");
	stu2->print();

	return 0;
}

输出结果:

num的地址:009DF63C,malloc的地址:00E4F618,this指向对象的地址:009DF7B8
我是张三
num的地址:009DF63C,malloc的地址:00E4B3C8,this指向对象的地址:00E4E178
我是李四

为什么要做上面的这个实验,我之前老想不明白,害,太菜了!其实new的底层是malloc,是在堆上开辟空间!

this指针存放在哪里,this指针可以为空吗

class A
{
public:
	void Print(){
		cout << "Print()" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}
// 上面的正常运行

class A
{
public:
	void PrintA(){
		cout << _a << endl; //显示写:this->_a,this指针为nullptr,解引用,程序崩溃
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->PrintA();
	return 0;
}

上面两段代码,在main函数中,都没有问题,p对象访问成员函数,因为Print成员函数的地址不在对象中,不会发生解引用!

3.静态成员
3.1.C语言中static的基本用法

在C语言中,static修饰的局部的变量可以,可以改变其是生命周期,使其生命周期随程序;对静态的全部变量和函数,限制在本源文件内使用;也就是说如果static修饰全局的变量或函数,跨一个源文件就不能使用!

下图是没有修饰的,可以跨源文件使用:

在这里插入图片描述

3.2.C++中的static关键字

C++中声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰成员函数,称之为静态成员函数静态成员变量一定要在类外进行初始化,类中的只是声明

#include<iostream>
using namespace std;

void sum(int x, int y) {}
int g_val = 5;

class Math
{
public:
	const static int _num = 0; // 这样在类内定义静态成员变量也是可以的,不推荐
	static void sum(int x, int y) {}
private:
	static int _result; // 这里只是声明!
	
};
int Math::_result = 5; // 定义并初始化!

int main()
{
	printf("全局的变量:%p, Math类中的静态函数:%p\n", sum, Math::sum);
	printf("全局的变量:%p, Math类中的静态变量:%p\n", &g_val, &Math::_num);

	return 0;
}

输出结果:

全局的变量:003A12B7, number类中的静态函数:003A1073
全局的变量:003AA000, number类中的静态变量:003AA1A8

静态成员变量:会被类的所有对象共享,包括派生类的对象;static修饰变量(全局,局部,成员)和全局变量一样放在全局的数据区在来编译器编译的时候就会开辟空间并完成初始化!(有资料说,静态成员变量因为构造函数的问题,在使用到相关代码才会初始化,但是我通过调试是在加载的时候就初始化的,害!)

静态成员函数:静态成员函数没有隐藏的this指针,不能访问任何非静态成员;但是非静态函数却能任何静态成员;

类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问,当然. 静态成员也是类的成员,受public、protected、private 访问限定符的限制!

实现一个类,计算程序中创建出了多少个类对象

class A
{
public:
	A() { ++_scount; }
	A(const A& t) { ++_scount; }
	~A() { --_scount; }
	static int GetACount() { return _scount; }
private:
	static int _scount;
};
int A::_scount = 0;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/376676.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多路服务器技术如何处理大量并发请求?

在当今的互联网时代&#xff0c;随着用户数量的爆炸性增长和业务规模的扩大&#xff0c;多路服务器技术已成为处理大量并发请求的关键手段。多路服务器技术是一种并行处理技术&#xff0c;它可以通过多个服务器同时处理来自不同用户的请求&#xff0c;从而显著提高系统的整体性…

零基础学Python(7)— 基本输入与输出

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。从第一个Python程序开始&#xff0c;我们一直在使用print()函数向屏幕上输出一些字符&#xff0c;这就是Python的基本输出函数。除了print()函数&#xff0c;Python还提供了一个用于进行标准输入的input()函数&#xff0c;…

成员对象与封闭类

1. 成员对象与封闭类 类里有其他对象则该对象叫成员对象&#xff1b;有成员对象的类叫 封闭类&#xff1b;上例中&#xff0c;如果CCar类不定义构造函数&#xff0c;则会使用默认的无参构造函数&#xff0c;那么下面的语句会编译出错: 因为编译器不明白CCar类中的tyre成员对象…

node.js后端+小程序前端+mongoDB(增删改查)

前言 今天我对比了以下node.js的express与python的fastAPI&#xff0c;我决定我还是出一期关于node.jsmangoDB小程序的小案例吧。 不是python的fastAPI不好用&#xff0c;因为fastAPI是python较新的技术&#xff0c;我不敢果断发出教学文章&#xff08;这件事情还是留着给pyt…

《幻兽帕鲁》攻略:0基础入门及游戏基础操作 幻兽帕鲁基础设施 幻兽帕鲁基础攻击力 Mac苹果电脑玩幻兽帕鲁 幻兽帕鲁加班加点

今天就跟大家聊聊《幻兽帕鲁》攻略&#xff1a;0基础入门及游戏基础操作。 如果想在苹果电脑玩《幻兽帕鲁》记得安装CrossOver哦。 以下纯干货&#xff1a; CrossOver正版安装包&#xff08;免费试用&#xff09;&#xff1a;https://souurl.cn/Y1gDao 一、基础操作 二、界面…

生成式学习,特别是生成对抗网络(GANs),存在哪些优点和缺点,在使用时需要注意哪些注意事项?

生成对抗网络&#xff08;GANs&#xff09; 1. 生成对抗网络&#xff08;GANs&#xff09;的优点&#xff1a;2. 生成对抗网络&#xff08;GANs&#xff09;的缺点&#xff1a;3. 使用生成对抗网络&#xff08;GANs&#xff09;需要注意的问题 1. 生成对抗网络&#xff08;GANs…

RabbitMQ的延迟队列实现[死信队列](笔记二)

上一篇已经讲述了实现死信队列的rabbitMQ服务配置&#xff0c;可以点击: RabbitMQ的延迟队列实现(笔记一) 目录 搭建一个新的springboot项目模仿订单延迟支付过期操作启动项目进行测试 搭建一个新的springboot项目 1.相关核心依赖如下 <dependency><groupId>org.…

设计模式理解:单例模式+工厂模式+建设者模式+原型模式

迪米特法则&#xff1a;Law of Demeter, LoD, 最少知识原则LKP 如果两个软件实体无须直接通信&#xff0c;那么就不应当发生直接的相互调用&#xff0c;可以通过第三方转发该调用。其目的是降低类之间的耦合度&#xff0c;提高模块的相对独立性。 所以&#xff0c;在运用迪米特…

【机器学习】机器学习流程之收集数据

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…

有趣的CSS - 旋转的太极图

目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整体效果 使用 :before 、:after 伪元素以及 animation 属性画一个顺时针旋转的太极图。 核心代码部分&#xff0c;简要说明了写法思路&#xff1b;完整代码在最后&#xff0c;可直接复…

PKI - 03 密钥管理(如何进行安全的公钥交换)

文章目录 Pre密钥管理面临的挑战安全密钥管理的几种方式手动密钥交换与确认受信任的介绍 Pre PKI - 02 对称与非对称密钥算法 密钥管理面临的挑战 密钥管理面临的挑战主要包括以下几点&#xff1a; 安全的公钥交换&#xff1a;在使用基于非对称密钥算法的服务之前&#xff0c…

Hadoop3.x基础(4)- Yarn

来源&#xff1a;B站尚硅谷 目录 Yarn资源调度器Yarn基础架构Yarn工作机制作业提交全过程Yarn调度器和调度算法先进先出调度器&#xff08;FIFO&#xff09;容量调度器&#xff08;Capacity Scheduler&#xff09;公平调度器&#xff08;Fair Scheduler&#xff09; Yarn常用命…

回归预测 | Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现ABC-BP人工蜂群算法优化BP神经网络多变量回归预测&#x…

盘点Java集合(容器)概览,Collection和Map在开发中谁用的最多?

写在开头 在Java的世界里万物皆对象。但我认为是万物皆数据&#xff0c;世界由各种各样数据构建起来&#xff0c;我们通过程序去实现数据的增删改查、转入转出、加减乘除等等&#xff0c;不同语言的实现方式殊途同归。由此可见&#xff0c;数据对于程序语言的重要性。 这段话…

Spring Boot 001 环境配置以及初始化项目

知识储备 后端&#xff1a;JavaSE, SSM&#xff08;SpringSpringMVCMyBatis&#xff09; 前端&#xff1a;HTML, CSS, Javascript 环境准备 JDK17下载 Java Downloads | Oracle 安装方式 JDK17在Windows安装以及环境变量配置&#xff08;超详细的教程&#xff09;_jdk17安装…

功能强大的国外商业PHP在线教育系统LMS源码,直播课程系统

源码介绍 Proacademy是在线教育一体化的解决方案&#xff0c;用于创建类似于Udemy、Skillshare、Coursera这种在线教育市场。 这个平台提供在线课程&#xff0c;现场课程&#xff0c;测验等等&#xff0c;并有一个基于实际业务需要的高级认证插件&#xff0c;程序基于Laravel…

NLP中的嵌入和距离度量

本文将深入研究嵌入、矢量数据库和各种距离度量的概念&#xff0c;并提供示例和演示代码。 NLP中的嵌入 嵌入是连续向量空间中对象、单词或实体的数值表示。在NLP中&#xff0c;词嵌入捕获词之间的语义关系&#xff0c;使算法能够更好地理解文本的上下文和含义。 让我们试着用…

国考省考行测:平行结构体

国考省考行测&#xff1a;平行结构体 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知识点 遇…

微信小程序(三十七)选项点击高亮效果

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.选择性渲染类 2.以数字为需渲染内容&#xff08;数量&#xff09; 源码&#xff1a; index.wxml <view class"Area"><!-- {{activeNumindex?Active:}}是选择性添加类名进行渲染 -->&l…

【蓝桥杯冲冲冲】[NOIP2017 提高组] 宝藏

蓝桥杯备赛 | 洛谷做题打卡day29 文章目录 蓝桥杯备赛 | 洛谷做题打卡day29[NOIP2017 提高组] 宝藏题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2提示题解代码我的一些话[NOIP2017 提高组] 宝藏 题目背景 NOIP2017 D2T2 题目描…