【C++】static静态关键字

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、static的概念
  • 二、static引入
  • 三、static详解
  • 四、静态和非静态的访问关系
  • 五、面试题

一、static的概念

【概念💬】:声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。

二、static引入

我们来看一道题目: 👇

💌面试题:实现一个类,计算程序中创建出了多少个类对象

首先,分析一下可以知道我们去实例化出一个对象的时候,无非是调用构造或者是拷贝构造,或者是通过一些传参返回的方式去构造对象。这样的话,我们知道必须要使用一个全局的变量来保存记录值。
对于这道题也有两种解决方案:
1️⃣方法一:在全局定义变量

#include<iostream>

int count = 0;
class A {
public:
	A()
	{
		count++;
	}
	A(const A& a)
	{
		count++;
	}
};

void func(A a)
{
	count++;
}
int main()
{
	A aa1;
	A aa2(aa1);

	func(aa1);
	std::cout << count << std::endl;
	return 0;
}

下面是调试动图:
在这里插入图片描述
通过调试,可以清楚的看到哪些地方使用了构造以及拷贝构造。
【注意】:这里定义的count会和std库里发生冲突。所以在使用的时候,为了防止报错,我们就要正确的使用命名空间。养成良好习惯,不要使用using namesapce std;全部展开。

❌此种方法缺乏安全性。
因为count是一个全局变量,那么它的生命周期就是从定义开始到main函数结束的时候销毁,这任何地方都是可以访问到的,并且它还不具有常性可以做任意修改,这其实也就缺乏了一定的安全性。

三、static详解

2️⃣方法二:使用static修饰

在C++中就引入了这样一个东西,把count作为类的成员变量。这样写,count是属于每个对象的。

class A {
public:
	A()
	{
		count++;
	}
	A(const A& a)
	{
		count++;
	}
private:
	static int count;
};

此时,我们给加上static,这个count就是属于这个类的,创建出的所有对象也都共享这个count;也就引出了如下特性:
🚩1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

🚩2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

class A {
public:
	A()
	{
		count++;
	}
	A(const A& a)
	{
		count++;
	}
private:
	static int count;
};
int count = 0;

但是我们发现会出现下面问题,这又是为什么呢?
在这里插入图片描述

原来是我在外部定义时,没有 指明count的出处。此时,我们只需要加上作用域即可。

int A::count = 0;

【补充】为什么不能在类中直接声明+定义呢?

  • 上面刚学习了构造函数的初始化列表,在类内直接定义是因为缺省值是给到构造函数的初始化列表用的,初始化列表初始化的是非静态成员,是属于当前对象的;而静态成员是属于所有对象的,是共有的,需要在全局区域定义。

🚩3. 静态成员也是类的成员,受public、protected、private 访问限定符的限制
运行发现出现下面问题,
在这里插入图片描述

🚩4. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
如下:

std::cout << aa1.count << std::endl;
std::cout << A::count << std::endl;
std::cout << A().count << std::endl;

尤其注意第三种,使用匿名对象 来访问。

🚩 5. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
这点通过以前的学习已经是十分清楚,静态成员函数是全局的,在静态区没有this指针,但普通的成员变量都是属于当前对象的,需要通过this指针来访问。

四、静态和非静态的访问关系

🔸静态成员函数不能调用非静态成员函数。
🔸静态成员函数内部可以调用静态的成员变量或者函数
🔸非静态成员函数可以调用类的静态成员函数

五、面试题

1.全局静态变量

  • 在全局变量前加上关键字 static,全局变量就定义成一个全局静态变量
  • 初始化:末经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化)
  • 存储位置:数据段(静态区、全局区)
  • 作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。缩小范围

2.局部静态变量

  • 在局部变量之前加上关键字 static,局部变量就成为一个局部静态变量。
  • 初始化:末经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化)
  • 存储位置:数据段(静态区、全局区)
  • 作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变

3.静态函数

利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数

  • 在函数返回类型前加 static,函数就定义为静态函数。函数的定义和声明在默认情况下都是 extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。

4.类的静态成员变量

  • 在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象共用

5.类的静态函数

  • 类静态成员函数和静态类成员变量一样,它们都属于类的静态成员,它们都不是对象成员,没有this指针。因此,对静态成员的引用不需要用对象名。
  • 是一个公共的函数。

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

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

相关文章

Rust 数据结构与算法:4栈:用栈实现进制转换

2、进展转换 将十进制数转换为二进制表示形式的最简单方法是“除二法”&#xff0c;可用栈来跟踪二进制结果。 除二法 下面实现一个将十进制数转换为二进制或十六进制的算法&#xff0c;代码如下&#xff1a; #[derive(Debug)] struct Stack<T> {size: usize, // 栈大…

【机器学习笔记】5 机器学习实践

数据集划分 子集划分 训练集&#xff08;Training Set&#xff09;&#xff1a;帮助我们训练模型&#xff0c;简单的说就是通过训练集的数据让我们确定拟合曲线的参数。 验证集&#xff08;Validation Set&#xff09;&#xff1a;也叫做开发集&#xff08; Dev Set &#xf…

【C++】 为什么多继承子类重写的父类的虚函数地址不同?『 多态调用汇编剖析』

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 本篇文章主要是为了解答有…

LeetCode Python -18.四数之和

目录 题目答案运行结果 题目 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#x…

OpenTitan- 开源安全芯片横空出世

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

前端网络安全笔记

本文主要涉及6个内容&#xff1a; HTTP与HTTPS同源策略&#xff08;Same-origin policy&#xff0c;简称 SOP&#xff09;/ 跨域资源共享&#xff08;Cross-Origin Resource Sharing&#xff0c;简称 CORS&#xff09;跨站脚本攻击&#xff08;Cross-Site Scripting&#xff0…

Java中的String类的常用方法(对于字符串的常用操作)

目录 一、获取指定索引的字符 二、 获取指定字符或者字符串的索引位置 三、判断字符串是否以指定内容开头或结尾 四、替换指定的字符或者是字符串 五、获取字符串的子串 六、将字符串转换为字符数组 七、比较字符串的内容是否相等 八、连接字符串 九、比较两个字符串的大…

JVM(5)面试篇

1 什么是JVM&#xff1f; 关联课程内容 基础篇-初识JVM基础篇-Java虚拟机的组成 回答路径 JVM的定义作用功能组成 1、定义&#xff1a; JVM 指的是Java虚拟机&#xff08; Java Virtual Machine &#xff09;。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是…

ArduPilot开源飞控之硬件SBC分析

ArduPilot开源飞控之硬件SBC分析 1. 源由2. Companion Computer2.1 APSync【不推荐&#xff0c;无更新】2.2 DroneKit【不推荐&#xff0c;无更新/SDK】2.3 FlytOS【不推荐&#xff0c;闭源】2.4 Maverick【不推荐&#xff0c;闭源】2.5 ROS【专门讨论&#xff0c;开源/复杂】2…

C/C++重点解析——内存管理

1. C/C内存分布 我们先来看一段代码和其相关问题&#xff1a; int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd"…

HGAME2024 WEEK2 wp webmisc

web What the cow say? 进入容器有个输入框&#xff0c;尝试ssti、命令执行、代码执行等&#xff0c;最后发现可使用反引号执行命令&#xff1b; 输入 nl app.py 可查看源代码&#xff0c;有功能具体实现、过滤之类的&#xff1b; flag在 /flag_is_here home/flag_c0w54y 中…

【NLP】MHA、MQA、GQA机制的区别

Note LLama2的注意力机制使用了GQA。三种机制的图如下&#xff1a; MHA机制&#xff08;Multi-head Attention&#xff09; MHA&#xff08;Multi-head Attention&#xff09;是标准的多头注意力机制&#xff0c;包含h个Query、Key 和 Value 矩阵。所有注意力头的 Key 和 V…

AI中的直方图均衡

目标 在本教程中&#xff0c;您将学习&#xff1a; 什么是图像直方图以及它为什么有用使用 OpenCV 函数 cv&#xff1a;&#xff1a;equalizeHist 均衡图像的直方图 理论 什么是图像直方图&#xff1f; 它是图像强度分布的图形表示。它量化了所考虑的每个强度值的像素数。…

搜索专项---最短路模型

文章目录 迷宫问题武士风度的牛抓住那头牛 一、迷宫问题OJ链接 本题思路:只需要记录各个点是有哪个点走过来的&#xff0c;就能递推得出路径。记录前驱假设从 1,1 这个点向下走到了2, 1&#xff0c;则将2,1这个点的前驱记为1,1。这样&#xff0c;将整张地图 bfs 后&#xff0c…

[嵌入式系统-14]:常见实时嵌入式操作系统比较:RT-Thread、uC/OS-II和FreeRTOS、Linux

目录 一、实时嵌入式操作系统 1.1 概述 1.2 什么“实时” 1.3 什么是硬实时和软实时 1.4 什么是嵌入式 1.5 什么操作系统 二、常见重量级操作系统 三、常见轻量级嵌入式操作系统 3.1 概述 3.2 FreeRTOS 3.3 uC/OS-II 3.4 RT-Thread 3.5 RT-Thread、uC/OS-II、Free…

LGAMEFI基于BPL公链开发的第一生态:开启RWA游戏娱乐与DeFi融合的新纪元

在去中心化金融&#xff08;DeFi&#xff09;与游戏娱乐的结合趋势中&#xff0c;BPL公链上的LGAMEFI项目代表了前沿的技术革新和市场领导。这种将web2上成熟页游进行RWA链改&#xff0c;不仅仅是将游戏热门领域融合&#xff0c;更是在寻找一种全新的参与者经验&#xff0c;将玩…

Pod 和容器的设计模型

一、为什么需要 Pod&#xff1a; 1、容器的基本概念&#xff1a; 容器的本质实际上是一个进程&#xff0c;是一个视图被隔离&#xff0c;资源受限的进程。容器里面 PID1 的进程就是应用本身&#xff0c;这意味着管理虚拟机等于管理基础设施&#xff0c;但管理容器却等于直接管…

拿捏单链表

目录 引言 一&#xff1a;链表的定义 二&#xff1a;单链表的定义 三&#xff1a;单链表的增删查改 1.单链表增删查改及遍历的声明 注&#xff1a;在测试中创建指向头结点的指针plist 2.二级指针应用的说明 3.单链表的遍历 4.创建节点 5.单链表的插入 (1)头插 …

Linux操作系统——命名管道

我们前面说的管道都是只能具有血缘关系的进程进行进程间通信&#xff0c;如果我想让两个毫不相干的进程进行通信呢&#xff1f;那就需要来谈谈命名管道了。 命名管道 管道应用的一个限制就是只能在具有共同祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。如果我们想…

软考 系统分析师系列知识点之信息系统战略规划方法(11)

接前一篇文章&#xff1a;软考 系统分析师系列知识点之信息系统战略规划方法&#xff08;10&#xff09; 所属章节&#xff1a; 第7章. 企业信息化战略与实施 第4节. 信息系统战略规划方法 7.4.7 价值链分析法 价值链分析&#xff08;Value Chain Analysis&#xff0c;VCA&am…