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。

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

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

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

相关文章

【DP】mobiusp正在创作乐曲

输入样例1&#xff1a; 5 2 1 7 7 1 3 输出样例1&#xff1a; 2 输入样例2&#xff1a; 10 3 2 5 6 4 4 5 7 3 5 6 输出样例2&#xff1a; 1 #include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; typede…

jpom学习

jpom学习 整理jpom 一键安装 部署会需要 mvn跟jdk环境 # 安装服务端和 jdk、maven 环境 yum install -y wget && \ wget -O install.sh https://jpom.top/docs/install.sh && \ bash install.sh Server jdkmvndocker安装 安装docker挂载方式安装 docker …

【Docker】Docker 仓库管理和Docker Dockerfile

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

php订单发起退款(余额和微信支付)

index.html <a class="btn btn-danger btn-change btn-tuikuan btn-disabled" href="javascript:;"><i class="fa fa-tuikuan"></i> 订单退款</a>-->order.js // 为表格绑定事件Table.api.bindevent(table);//退款…

基于指数分布算法优化概率神经网络PNN的分类预测 - 附代码

基于指数分布算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于指数分布算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于指数分布优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

【docker】docker安装与优化

目录 一、安装Docker 1、关闭防火墙 2、安装依赖包 3、设置阿里云镜像源 4、安装Docker-CE社区版并设置为开机自启动 5、查看Docker信息 二、设置镜像加速 1、申请加速地址 2、实现加速操作 三、网络优化 1、如何网络优化 2、具体操作 四、docker-server端配置文件…

3.读取字符串【2023.11.25】

1.问题描述 请使用 input 函数读取一串字符串&#xff0c;然后将其输出。 2.解决思路 输入一行字符串。 将读入的变量输出。 3.代码实现 strinput("请输入一个字符串") print(str)4.运行结果

Word打印模板,打印效果更出众丨三叠云

Word打印模板 路径 表单设置 >> 打印设置 功能简介 新增「Word打印模板」(beta版)。 Word 打印模板是指&#xff0c;在 Word 文档的基础上插入表单中的字段代码&#xff0c;打印时即可根据 Word 文档的格式&#xff0c;对表单数据进行个性化打印。 Word 打印模板能…

knime 中没有column expressions,怎么下载

knime 中没有column expressions&#xff0c;怎么下载 1、打开view&#xff0c;然后找到knime hub&#xff0c;column expression 2、往里面拖动&#xff0c;就可以安装了 3、然后会出现重启&#xff0c;搜索就可以出现啦

10.打印楼梯图案和笑脸【2023.11.25】

1.问题描述 打印楼梯图案和笑脸 2.解决思路 3.代码实现 #include<stdio.h> int main(){printf("11\n");for(int i0;i<10;i){for(int j0;j<i;j){printf("FF"); }printf("\n");} return 0; }4.运行结果

springboot项目同时启动web服务和grpc服务

springboot项目同时启动web服务和grpc服务 一. 创建项目二. 引入依赖三. 测试3.1 http服务3.2 grpc服务 四. 整体代码结构 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 一. 创建…

力扣二叉树--总结篇(1)

前言 七天写了二十道题&#xff0c;前面感觉不错&#xff0c;后面越来越写不出来&#xff0c;刷题的心境和效果已然发生了变化。写个阶段总结&#xff0c;及时调整。 内容 先是二叉树的遍历 前序&#xff0c;中序&#xff0c;后序&#xff0c;即对应的递归&#xff0c;迭代…

科研/比赛必备工具及系列笔记集合

科研/比赛必备工具及系列笔记集合 零、前言一、常用工具系列1.1 笔记平台使用感受系列1.2 常用开发平台系列 二、论文系列2.1 检索工具系列2.2 投稿调研系列2.3 常见国际期刊/会议2.4 常见中文核心期刊/会议 三、文献系列3.1 画图工具系列3.2 翻译工具系列3.3 英文纠正系列3.4 …

Mysql基础操作(命令行)

文章目录 Mysql基础操作&#xff08;命令行&#xff09;背景创建数据库选择数据库查看所有表查看表结构向表插入数据插入第一条插入第二条插入第三条 查询表数据修改表数据删除表数据 Mysql基础操作&#xff08;命令行&#xff09; 背景 docker安装mysql8&#xff0c;映射本地…

【Spring源码】Spring Event事件

目录 1、前言 2、什么是Spring Event&#xff1f; 3、基本使用 3.1、定义事件 3.2、发布事件 3.3、监听事件 3.3.1、继承ApplicationListener 3.3.2、使用EventListener注解 4、Spring Event是同步还是异步&#xff1f; 4.1、源码实现 4.2、如何实现异步 4.2.1、使用…

台球厅计时软件收费怎么设置时间,佳易王桌球计时计费灯控系统

台球厅计时软件收费怎么设置时间&#xff0c;佳易王桌球计时计费灯控系统 软件可以连接配套的灯控设备&#xff0c;点击计时开灯&#xff0c;则灯打开&#xff0c;结账后关灯。 一、佳易王桌球棋牌计时计费软件部分功能简介&#xff1a; 1、计时计费功能 &#xff1a;开台时间…

论文阅读_生成式Agent

英文名称: Generative Agents: Interactive Simulacra of Human Behavior 中文名称: 生成代理&#xff1a;**人类行为的交互式模拟** 文章: http://arxiv.org/abs/2304.03442 代码: https://github.com/joonspk-research/generative_agents 作者: Joon Sung Park 机构: 斯坦福大…

如何评估一个论坛或峰会值不值得参加?

现在的论坛和峰会非常多&#xff0c;且都宣传的非常高端&#xff0c;很多人为了不错过机会像赶场一样总在参会路上。但究竟什么样的论坛或峰会才值得一去呢&#xff1f; 评估一个论坛或峰会是否值得参加&#xff0c;需要考虑多个因素。 1、主题与你的兴趣或职业相关性&#xf…

5个AI绘图工具,强到离谱国内可用!

话不多说&#xff0c;先来看看AI生成的图片吧~ 1、AI-Chat&#xff08;ChatGPT平替版&#xff09; 传送门&#xff1a;点此访问手机端&#xff1a;AIChat手机版 传送门&#xff1a;点此访问PC端&#xff1a;AIChat PC版 支持“AI智能绘画”输入你想要的描述词或图片就能快速生…

【vue实战项目】通用管理系统:学生列表

本文为博主的vue实战小项目系列中的第五篇&#xff0c;很适合后端或者才入门的小伙伴看&#xff0c;一个前端项目从0到1的保姆级教学。前面的内容&#xff1a; 【vue实战项目】通用管理系统&#xff1a;登录页-CSDN博客 【vue实战项目】通用管理系统&#xff1a;封装token操作…