P12 C++静态关键字static

目录

01 前言

02 静态变量static

03 extern关键字

04 静态函数

最后的话


01 前言

static 关键字在 C++ 中有两个意思,这个取决于上下文。

第一种情况是在类或结构体外部使用 static 关键字,另一种是在类或者结构体内部使用 static。

  1. 类外面的 static 意味着你声明为 static 的内容,将只是在内部链接,这意味着它只能对它所在的翻译单元可见。
  2. 类或结构体内部的静态变量 static 意味着该变量将与类的所有实例共享内存,这意味着该静态变量在你的类创建的所有实例中,静态变量只有一个实例。类似的事情也适用于类中的静态方法。

本期不讨论静态 static 在类或结构体范围内的实际含义,只关注在类和结构体外部的 static。类内部的static放在下一期讨论

02 静态变量static

static int s_data = 15;

我在一个完全空的 C++ 文件中定义了一个静态变量,使用惯例使用 S_ 来表示这个变量是静态的,将其值设置为 5。它整体上看起来和其他变量是一样的,只不过在它前面的是 static 关键字,这意味着这个变量只会在当前这个转换单元内部链接。

静态变量或函数意味着当需要将这些函数或变量与实际定义的符号链接时,链接器不会在这个转换单元的作用域之外的地方寻找那个符号定义。

我们拿实际的代码来解释一下。

在第一个例子中21.1.cpp,我们创建了一个静态变量s_data,并将它设为 15,然后去另一个 C++ 文件21.cpp,也就是另一个转换单元,一个带有main函数空白 C++ 文件。在这里创建一个全局变量。将它与之前静态变量设置一样的名字。其值设置为十,打印这个变量。

运行之后,我们可以看到,程序是可以编译的,不会遇到任何问题。

然后我们回到 21.1.cpp 文件,删除了static 关键字。再次编译刚刚的代码。你会发现当它进入链接状态阶段时,会报一个链接错误。因为这个 s_data 变量已经在另一个转换单元中定义过了,当然是这样的,我们不能有两个同名的全局变量。

03 extern关键字

那么只有这一种调整方法了吗?当然不是。

我们可以这样修改。

  

这样操作意味着它会在外部转换单元中寻找 s_data 变量。这被称为 external linkage 或者 external linking。

现在运行代码也是没有问题了的。它可以输出 15,它引用了另外一个文件中的 s_data 变量的值。

这个时候如果我再次将另外一个文件中的 s_data标记为静态。——这个过程有点像在类中声明一个私有变量,链接器在全局作用域下将不会看到这个变量。程序它还是会报错,因为我们已经做了有效的标记,这个变量已经是私有的了。

04 静态函数

接下来我们试一下函数 function。

我在 21.cpp 文件中定义一个 function函 数。然后在 21.1.cpp 中也定义一个具有相同签名的函数,返回值也是 void。

编译一下这个程序。我们在链接阶段同样得到一个重复的符号错误。

回到 Static.cpp 文件中,使用 static 将它标记为静态的。链接器开始工作时,根本不会看到这个静态的函数。程序会顺利编译,不会得到任何错误。

 这就是 C++ 中静态的全部含义。

当你在类和结构体之外使用静态时,它只是意味着你声明的静态函数或静态变量只会在它所在的文件中被看到。

如果你想在头文件中声明一个静态变量,将头文件包含在两个不同的 C++ 文件中。其实和上面的例子是一样的,都是在两个转换单元中都声明了相同的 s_data 变量为静态变量。当然,当你包含那个头文件时,它会复制所有内容并将其粘贴在 C++ 文件中。也就是将一个静态变量放到两个不同的转换单元中,这个你要留意一下。

#include <iostream>extern int s_data;void funtion()
{}int main()
{std::cout <<s_data << std::endl;return 0;
}

最后的话

那么我们使用 static 的理由是什么呢?

你可以参考一下我们为什么要在类中使用 private?

如果你不需要变量是全局变量,你就需要尽可能多的使用静态变量。一旦在全局作用域下声明了东西,如果没有设定为static,链接器将会跨编译单元进行链接。这意味着你已经创建了一个完全全局的变量,它可以在任何地方使用,这可能会导致一些非常糟糕的 bug。

归根到底,全局变量是不好的。我不太喜欢用全局变量,也不建议你使用。除非你真的需要他们跨转换单元链接。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据库】物理操作的一趟扫描算法机制原理,理解关系代数据与物理计划的关系,以及代价评估的应用和算法优化

一趟扫描算法 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定期更新…

红外遥控实验

本章&#xff0c;我们将介绍 STM32F103 对红外遥控器的信号解码。STM32 板子上标配的红外接收 头和一个小巧的红外遥控器。我们将利用 STM32 的输入捕获功能&#xff0c;解码开发板标配的红外遥控 器的编码信号&#xff0c;并将编码后的键值在 LCD 模块中显示出来。 红外遥控技…

BTC 复兴:Ordinals 带来创新活力,BitVM 与 BitStream 相继问世

除了备受瞩目的 ETF&#xff0c;今年 Bitcoin 生态迎来全新的发展活力和机遇。Ordinals 协议的横空出世&#xff0c;以此为基础诞生的 BRC20 协议给整个比特币生态带去了一波新的能量&#xff0c;迎来铭文热度高涨。而诸如 BitVM、BitStream 等新技术甫一问世&#xff0c;便引发…

MT6893_天玑 1200芯片规格参数介绍_datasheet规格书

天玑 1200(MT6893)是一款专为旗舰级全新5G芯片&#xff0c;它融合了先进的AI、相机和多媒体技术&#xff0c;为用户带来令人惊叹的体验。采用先进的6纳米制程设计&#xff0c;内置各种先进技术。该芯片采用旗舰级的八核CPU架构设计&#xff0c;支持16GB强大的四通道内存以及双通…

重庆数字孪生技术推进制造业升级,工业物联网可视化应用加速

重庆数字孪生、5G、人工智能、物联网、大数据等新一代信息技术的出现及终端计算设备的发展&#xff0c;带来了研发模式、生产模式、消费模式、体制机制的系统性变革&#xff0c;企业应该建设适应工业4.0时代发展要求的新型生产体系。巨蟹数科数字孪生智能工厂通过部署多样化用例…

初出茅庐的小李博客之C语言必备知识共用体

C语言必备知识共用体 共用体是一种构造数据类型&#xff0c;有时候也称之为联合体。 它的用途&#xff1a; 使几个不同类型的变量共占一段内存。 共用体举例 union 共用体名 { 类型标识符 成员名;类型标识符 成员名; };union data //共用体名字是data{ int i; …

leetcode刷题:17.电话号码的字母组合

leetcode原题网页 题目描述&#xff1a;给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 思路&#xff1a;使用vector&#x…

Guitar Pro软件8.0官方最新版本下载

Guitar Pro 8是一款由法国Arobas Music公司开发的吉他学习与MIDI音序制作辅助软件&#xff0c;它具有丰富的功能&#xff0c;包括吉他谱、六线谱、四线谱绘制、打印、查看、试听等方面&#xff0c;能够帮助音乐爱好者更方便地进行音乐学习和创作。Guitar Pro 8拥有独特的gtp格式…

遥遥领先!TinyEngine 低代码引擎更新升级!AI 已成功部署!

官网更新 1. 协议规范优化更新 协议规范交互优化&#xff0c;能够在一页里面自由切换&#xff0c;提高用户体验&#xff0c;后端SDK文档字段描述补齐&#xff0c;助力开发者自助进行服务端开发。 2.使用手册全新改版 去掉之前的学院课程&#xff0c;新设计新分类让结构一目了…

【cf 158 c】

给你一个整数数组 a1,a2,…,an ( )。在一次操作中&#xff0c;你可以选择一个整数 x ( )&#xff0c;并用 ⌊⌋ 替换 ai ( ⌊y⌋ 表示将 y 舍入为最接近的整数)。 来替换从 1 到 n 的所有 i。请注意&#xff0c;每次操作都会影响数组中的所有元素。打印使数组中所有元素相等所…

可验证随机函数(VRF)

文章目录 一、背景以及场景共识发展第一代 POW “以力取胜”第二代 POS/DPOS “民主投票”第三代 VRF “运气抽签” 二、可验证随机函数&#xff08;VRF&#xff09;快速开始1. VRF是什么?2. MD5 hash函数和VRF&#xff08;Verifiable Random Function&#xff09;区别3. VRF-…

【阿里云】图像识别 智能分类识别 项目开发(一)

语音模块和阿里云图像识别结合 环境准备 代码实现 编译运行 写个shell脚本用于杀死运行的进程 语音模块和阿里云图像识别结合 使用语音模块和摄像头在香橙派上做垃圾智能分类识别 语音控制摄像下载上传阿里云解析功能点实现 环境准备 将语音模块接在UART5的位置 在orange…