【C++】static静态关键字

news2024/11/29 20:37:37

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹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指针。因此,对静态成员的引用不需要用对象名。
  • 是一个公共的函数。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java并发基础:ConcurrentLinkedDeque全面解析!

内容概要 ConcurrentLinkedDeque类提供了线程安全的双端队列操作&#xff0c;支持高效的并发访问&#xff0c;因此在多线程环境下&#xff0c;可以放心地在队列的两端添加或移除元素&#xff0c;而不用担心数据的一致性问题。同时&#xff0c;它的内部实现采用了无锁算法&…

Web安全研究(六)

文章目录 HideNoSeek: Camouflaging(隐藏) Malicious JavaScript in Benign ASTs文章结构Introjs obfuscationmethodologyExample HideNoSeek: Camouflaging(隐藏) Malicious JavaScript in Benign ASTs CCS 2019 CISPA 恶意软件领域&#xff0c;基于学习的系统已经非常流行&am…

嵌入式Qt 计算器界面设计代码重构

一.计算器界面设计代码重构 计算器界面设计&#xff1a;嵌入式Qt 计算器界面设计-CSDN博客 重构的概念&#xff1a; 代码实现与代码重构的不同&#xff1a; 软件开发过程&#xff1a; 什么样的代码需要重构&#xff1a; 计算器界面代码重构的框架设计&#xff1a; 实验&#…

实现JNDI

实现JNDI 问题陈述 Smart Software Developer Ltd.想要开发一款Web应用程序,它使用servlt基于雇员ID显示雇员信息,雇员ID由用户通过HTML用户界面传递。雇员详细信息存储在Employee_Master表中。另外,Web应用程序应显示网站被访问的次数。 解决方案 要解决上述问题,需要执…

福布斯2023年推荐:十佳项目管理软件榜单揭晓

项目管理软件可以轻松规划项目、分配任务并保持团队井井有条&#xff0c;以便满足截止日期和目标。然而当今市场上有如此多的项目管理系统&#xff0c;选择适合您需求的正确选项可能很困难。为了提供帮助&#xff0c;福布斯小型企业顾问团队分析了数十家领先的提供商&#xff0…

【医学知识图谱 自动补全 关系抽取】生成模型 + 医学知识图谱 = 发现三元组隐藏的关系实体对

生成模型 医学知识图谱 发现三元组新关系实体对 提出背景问题&#xff1a;如何自动发现并生成医疗领域中未被标注的实体关系三元组&#xff1f;CRVAE模型 提出背景 论文&#xff1a;https://dl.acm.org/doi/pdf/10.1145/3219819.3220010 以条件关系变分自编码器&#xff08;…

【通讯录案例-归档解档 Objective-C语言】

一、接下来,我们来说这个“归档”、“解档”、 1.归档、解档、这一块儿呢 首先呢,我们这个目标啊,还是跟“代理”差不多,要会用, 一会儿给大家画一幅图,让大家去了解“归档”、“解档”、每一句话,到底都干了什么, 好,我们先新建一个项目, 新建一个项目 新建一个…

Python实现EMV指标计算:股票技术分析的利器系列(2)

Python实现EMV指标计算&#xff1a;股票技术分析的利器系列&#xff08;2&#xff09; 介绍算法解释&#xff1a; 核心代码&#xff1a;rolling函数介绍 完整代码&#xff1a;一定要看 介绍 先看看官方介绍&#xff1a; EMV(简易波动指标&#xff09; 用法 1.EMV 由下往上穿越…

“操作符大揭秘:一篇文章让你秒懂所有!”

目录 1. ⼆进制介绍 2. 原码、反码、补码 3. 移位操作符 4. 位操作符&#xff1a;&、|、^ 5. 逗号表达式 6. 下标访问[]、函数调⽤() 7. 操作符的属性&#xff1a;优先级、结合性 8. 整型提升 9. 算术转换 10. 表达式求值 正文开始&#xff1a; 1. ⼆进制 其实我…

Leetcode 1035 不相交的线

题意理解&#xff1a; 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在&#xff0c;可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#xff0c;这些直线需要同时满足满足&#xff1a; nums1[i] nums2[j]且绘制的直线不与任何其他连线&#xff…

MATLAB|【免费】高比例可再生能源电力系统的调峰成本量化与分摊模型

目录 主要内容 部分代码 结果一览 下载链接 主要内容 程序复现文献《高比例可再生能源电力系统的调峰成本量化与分摊模型》&#xff0c;从净负荷波动的角度出发&#xff0c;建立了调峰成本的量化与分摊模型&#xff0c;构造了无调峰需求的替代场景&#xff0c;将…

阿里云游戏服务器一年费用多少?

阿里云游戏服务器租用价格表&#xff1a;4核16G服务器26元1个月、146元半年&#xff0c;游戏专业服务器8核32G配置90元一个月、271元3个月&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云游戏专用服务器详细配置和精准报价&#xff1a; 阿里云游戏服务器租用价格表 阿…

【JavaEE进阶】 图书管理系统开发日记——陆

文章目录 &#x1f38b;前言&#x1f343;删除图书&#x1f6a9;约定前后端交互接口&#x1f6a9;完善前端代码&#x1f6a9;接口测试 &#x1f38d;批量删除&#x1f6a9;约定前后端交互接口&#x1f6a9;实现后端服务器代码&#x1f388;控制层&#x1f388;业务层&#x1f3…

Uipath 调用Python 脚本程序详解

Python 活动概述 UiPath.Python.Activities 是一个新的活动包&#xff0c;创建它是为了支持直接从工作流运行 Python 脚本和方法。 其包含以下活动&#xff1a; Python 作用域(Python Scope) - 为 Python 活动提供作用域的容器。 加载 Python 脚本(Load Python Script) - 将 P…

Servlet JSP-Eclipse安装配置Maven插件

Maven 是一款比较常用的 Java 开发拓展包&#xff0c;它相当于一个全自动 jar 包管理器&#xff0c;会导入用户开发时需要使用的相应 jar 包。使用 Maven 开发 Java 程序&#xff0c;可以极大提升开发者的开发效率。下面我就跟大家介绍一下如何在 Eclipse 里安装和配置 Maven 插…

(一)【Jmeter】JDK及Jmeter的安装部署及简单配置

JDK的安装和环境变量配置 对于Linux、Mac和Windows系统&#xff0c;JDK的安装和环境变量配置方法略有不同。以下是针对这三种系统的详细步骤&#xff1a; 对于Linux系统&#xff1a; 下载适合Linux系统的JDK安装包&#xff0c;可以选择32位或64位的版本。 将JDK的安装包放置…

ubuntu服务器部署gitlab docker并配置nginx反向代理https访问

拉取镜像 docker pull gitlab/gitlab-ce运行容器 docker run --detach \--publish 9080:80 --publish 9022:22 --publish 9443:443\--namegitlab \--restartalways \--volume /home/docker/gitlab/config:/etc/gitlab \--volume /home/docker/gitlab/logs:/var/log/gitlab \-…

今天:旧时是这样“破五迎福”

昨&#xff08;正月初四&#xff09;天&#xff0c;笔者——“ 人民体验官 ”&#xff0c; 为了推广人民日报官方微博文化产品所发表在10余个网站自媒体平台上的文章《今天&#xff1a;大年初四迎灶神爷》&#xff0c;不知何故被笔者寄居养老城市的自媒体论坛反复拒之门外&…

Spring Boot3自定义异常及全局异常捕获

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 目的 主要步骤 定义自定义异常类 创建全局异常处理器 手动抛出自定义异常 前置条件 已经初始化好一个…

使用一根网线,让Ubuntu和正点原子I.MX6ULL开发板互相ping通

1.硬件准备 准备一根网线即可 2. 让windows和I.MX6ULLping通 2.1 找根网线将I.MX6ULL和电脑连起来 2.2 让I.MX6ULL通电运行起来&#xff0c;我这里使用的是正点原子版本的内核、 2.3 进入电脑的网络连接后&#xff0c;按照如下步骤操作 2.4 将ip地址、子网掩码、默认网关…