019 - C++ 中的局部静态(local static)

news2024/12/28 8:25:06

在前几期里,我们了解了static关键字在特定上下文中的含义。

今天我们看一看另一个环境。我们可以在局部作用域中使用 static 来声明一个变量。

这种情况和我们之前看到的两种static有点不同。这次的局部静态 Local static 有更多的含义。

声明一个变量,我们需要考虑两种情况:变量的生命周期变量的作用域

生命周期指的是变量实际存在的时间。换句话说,在它被删除之前,它会在我们的内存中存在多久。而变量的作用域是指我们可以访问变量的范围。

所以如果在一个函数内部声明一个变量,我们不能在其它函数中访问它。我们声明的变量对于声明的函数是局部的。

局部静态

局部 local static 变量允许我们声明一个变量,它的生命周期基本上相当于整个程序的生命周期,然而它的作用范围却被限制在这个函数内。

在任何作用域中声明它都可以,这个和函数没有关系,刚才我只是用函数举了一个例子,它并不仅仅局限在函数内部,也可以在 if 语句中,可以在任何位置。

这就是为什么函数作用域中的 static 和类作用域中的 static之间没有太大区别的原因,因为生命周期实际是相同的。唯一的区别是在类作用域中,类中的任何东西都可以访问它(这个静态变量)。

如果你在函数作用域中声明一个静态变量,它将是那个函数的局部变量。对类来说也是局部变量。

让我们来看一些例子。

ihCjzv.png

我创建了一个函数。在其中声明一些静态变量。

这意味着当我第一次调用函数时,这个变量将被初始化为 0。然后所有对函数的后续调用实际上不会创建另一个全新的变量。

检验的方法很简单。

可以先把static删掉。每次调用函数都增加 i 的值,然后打印它的值。

ihC813.png

每一次调用这个函数时 i 都会被设置为 0。然后增加 1,通过调用函数来进行测试。

你可以看到1被打印了5次。

我们恢复 static。

其实这个时候非常类似于我把最初的声明移到函数外面。

ihCNCy.png

我们现在运行代码。 i 开始的时候是0,然后累加 5 次。

所以你会得到这样的结果。

ihCrX5.png

这样的写法没有任何问题。但是我们可以在任何地方访问 i。比如你可以在 function 函数调用之间让 i 等于 10。这可以极大的改变你的程序所做的事情。

所以如果你想要这样做,但又不希望让每个人都能访问这个变量。你可以在局部作用域下声明成 static。像我一开始写的程序那样。

这意味着我们第一次运行这个函数时,首先创建变量。并设为 0,后面它们都是指原来的变量。

运行这个程序,我们会得到和上面一样的结果。

ihC3K8.png

但是之前那个变量 i 在全局范围内是可见的,虽然它是函数的局部变量。

有些人不赞成使用这种方法,我不理解其中的原因,我不认为这有什么问题。

它确实有它的用处。上面的例子就是其中之一。

其他的实现方式

你可以使用其它方法实现完全相同的行为。比如你可以用类来实现。

我们再来看下一个例子。

ihCcUZ.png

这里有一个单例类。——单例类是只存在一个实例的类。

如果我想创建这个单例类,而不使用静态局部作用域,我就需要创建静态的单例实例。我们设置了一个指针。如果你想返回一个引用,我必须有一个返回 Singleton& 的 Get 函数,它是静态的,然后返回我的的实例。

当然,我需要声明这个实例,并把它默认设为空指针。这样我就有了一个单例类。

我可以调用 Singleton::Get,然后对它做任何我想做的事情。

比如我设置了一个方法 hello,在下面调用,我们就得到了一个可以使用的一个类实例。

ihCm3F.png

虽然可以,但是你不一定要非要这样做。

另一种方式就是你可以使用我们的新学的内容。local Static,代码可能是这个样子。

ihCpSH.png

我们得到了完全相同的行为。可以看到一切都保持不变。它可以成功运行,没有崩溃。

现在你可以看到我们的代码干净多了。

当然如果上面的例子没有 static 关键字,那么这个实例会在栈上面创建。代码运行到花括号的时候,函数作用域结束时就会被销毁。这是一个严重的错误,特别是还来引用它,如果只是复制了它,那不会有问题。但是我们返回的是一个对它的引用。这个就会出大问题。

通过添加静态,将它的生命周期延长到永远。我们第一次调用 get。它实际上会构造一个单例实例。接下来的时间。它只会返回这个已经存在的实例。

最后的话

这是一个很好的例子。当你想这样用的时候,不一定非要用单例类。可以通过替换掉初始化函数来实现。例如,你可能需要在程序中的某处调用一个静态初始化函数来创建所有对象。你就可以使用静态 get 方法之类的东西,在很多情况下用它来简化代码。

你可以看到它有很多用途,真的很好用,所以请多多练习使用它。

以上是我使用过程中的一些想法,大家有什么别的看法可以发在评论区哈。

下期再见。

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

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

相关文章

个人知识库(持续更新中)

打造一个属于自己的知识库 为什么会有这个知识库会记录什么内容基础知识Java核心Java WebMySQL 中间件&工具项目代码资源仿牛客社区Web开发华夏ERP软件 视频资源代码之外持续更新中… 为什么会有这个知识库 作为羊哥的死忠粉,当他谈到个人知识库这个东西的时候…

RS-485 基础知识:何时需要端接,以及如何正确端接

RS-485 网络的许多信号完整性和通信问题都源于端接,这可能是因为缺少端接或端接不正确。在 RS-485 基础知识系列的这一部分,我将讨论何时不需要端接 RS-485 网络,以及在需要端接时如何使用标准(并联)端接和交流电 (AC)…

【JavaEE】常见的锁策略与CAS的ABA问题

文章目录 1 常见的锁策略1.1 乐观锁与悲观锁1.2 轻量级锁与重量级锁1.3 自旋锁与挂起等待锁1.4 互斥锁与读写锁1.5 可重入锁与不可重入锁1.6 公平锁与非公平锁 2 CAS 操作2.1 CAS 简介2.2 CAS 的应用2.2.1 实现原子类2.2.2 实现自旋锁 3 CAS 的 ABA 问题写在最后 1 常见的锁策略…

Nacos 客户端的服务发现与服务订阅机制的纠缠 - 篇七

Nacos 客户端的服务发现与服务订阅机制的纠缠 - 篇七 历史篇章 🕐Nacos 客户端服务注册源码分析-篇一 🕑Nacos 客户端服务注册源码分析-篇二 🕒Nacos 客户端服务注册源码分析-篇三 🕓Nacos 服务端服务注册源码分析-篇四 &am…

最新入河排污口设置论证、水质影响预测与模拟、污水处理工艺分析及建设项目入河排污口方案报告书

随着水资源开发利用量不断增大,全国废污水排放量与日俱增,部分河段已远远超出水域纳污能力。近年来,部分沿岸入河排污口设置不合理,超标排污、未经同意私设排污口等问题逐步显现,已威胁到供水安全、水环境安全和水生态安全&#x…

ChatGPT探索系列之五:讨论人工智能伦理问题及ChatGPT的责任

文章目录 前言一、安全二、隐私和道德三、我们应该做什么总结 前言 ChatGPT发展到目前,其实网上已经有大量资料了,博主做个收口,会出一个ChatGPT探索系列的文章,帮助大家深入了解ChatGPT的。整个系列文章会按照一下目标来完成&am…

STM32(十六)正交编码器

一、简介 增量式编码器 增量式编码器也称为正交编码器,是通过两个信号线的脉冲输出来进行数据处理,一个输出脉冲信号就对应于一个增量位移,编码器每转动固定的位移,就会产生一个脉冲信号 通过读取单位时间脉冲信号的数量&#xff…

自动修改文章的软件-自动修改文案原创软件

有没有自动修改文章的软件 修改文章可能是很多人日常工作中必须完成的任务,但一般情况下,这需要人工完成。幸运的是,现在有很多文章修改软件可以帮助我们节省时间和精力。本文将向您介绍一款优秀的修改文章软件,名为147SEO&#…

SLAM论文速递【SLAM—— TwistSLAM:动态环境下的约束SLAM】—4.17(2)

论文信息 题目: Optimization RGB-D 3-D Reconstruction Algorithm Based on Dynamic SLAM 基于动态SLAM的RGB-D三维重建算法优化论文地址: https://ieeexplore.ieee.org/abstract/document/10050782发表期刊: IEEE Transactions on Instru…

Apache POI 实现用Java操作Excel完成读写操作

简介 Apache POI是一个用于操作Microsoft Office格式文件(包括xls、docx、xlsx、pptx等)的Java API库。POI全称为Poor Obfuscation Implementation,是Apache Software Foundation的一个开源项目。它提供了一组Java API,使得Java程…

LLM_StableDiffusion_studio发布

背景: 从chatgpt发布到现在已经超过半年时间,AGI的势头越来越猛。大家都在做各种的尝试和组合,把chatgpt通用的强大的知识表达和理解能力尝试应用在自己的业务场景。前期也是出现非常多的业务应用,但是主要还是围绕chatgpt本身已…

循环神经网络(RNN)简单介绍—包括TF和PyTorch源码,并给出详细注释

文章目录 循环神经网络(RNN)入门教程1. 循环神经网络的原理2. 循环神经网络的应用3. 使用keras框架实现循环神经网络3.1导入对应的库及加载数据集3.2.数据预处理3.3定义RNN模型3.4训练模型3.5测试模型 4.使用PyTorch框架实现上述功能—注释详细5.结论 循…

动静态库的制作和使用

动静态库 一,什么是库二,静态库的制作静态库原理 三,动态库的制作四,动态库的配置五,动态库的加载 一,什么是库 🚀库这个东西我们一直在使用,举个简单了例子,无论你是用…

netplan, NetworkManager, systemd-networkd简介

1、systemd-networkd简介 systemd-networkd是systemd 的一部分 ,负责 systemd 生态中的网络配置部分(systemd-networkd.service, systemd-resolved.service)。使用 systemd-networkd,你可以为网络设备配置基础的 DHCP/静态IP网络等,还可以配…

U8W/U8W-Mini使用与常见问题解决

U8W/U8W-Mini使用与常见问题解决 U8WU8W/U8W-mini简介准备工作U8W/U8W-mini在线联机下载U8W/U8W-mini脱机下载第一步,把程序下载到U8W/U8W-mini烧录器中:第二步,用U8W/U8W-mini烧录器给目标单片机脱机下载 U8W/U8W-mini烧录器使用中常见的问题…

初识Linux运维

一.初识Linux 1.Linux系统内核 内核提供了Linux系统的主要功能,如硬件调度管理的能力。 Linux内核是免费开源的,任何人都可以查看内核的源代码,甚至是贡献源代码。 2.Linux系统发行版 内核无法被用户直接使用,需要配合应用程…

淘宝iOS拍立淘微距能力探索与实现

画面模糊问题的源头也是来自用户的微距体验不佳,我们对问题深入分析,适当拆解。通过 Apple Development Doc 的查阅及实践,一步步抽丝剥茧,最终完美解决用户的体验痛点,也为我们自身沉淀了展示微距的能力。 前言 在最近…

Unix和Linux

UNIX 诞生于 20 世纪 60 年代末 Windows 诞生于 20 世纪 80 年代中期 Linux 诞生于 20 世纪 90 年代初 1965 年,贝尔实验室、美国麻省理工学院和通用电气公司联合发起了Multics 工程计划,目标是开发一种交互式的、具有多道程序处理能力的分时操作系统&a…

NTP服务与SSH服务

NTP:时间同步服务,采用UDP协议,端口号为123。 配置NTP时间服务器,确保客户端主机能和服务主机同步时间 首先,我们必须确保服务端与客户端在同一时区。 更改时区:timedatectl set-timezone asia/shanghai …

隋唐洛阳“西宫”:上阳宫的GIS视角

隋唐洛阳城简介 营建 隋大业元年(605年),在隋炀帝的授意下,隋代著名城市设计师宇文恺,在汉魏故城以西重新选址,历时8个月,日役劳工200万,兴建新都洛阳城。 城和苑 隋唐洛阳城采用…