C++:Static

1 在内存中所在的位置

回想C++程序中内存的划分是什么呢?从上到下首先是内核空间,然后是栈内存,内存映射段,堆,数据段,和代码段。用一张图的解释就是:

在这里主要探讨static,因此主要讨论数据段。数据段用于存储静态全局变量、静态局部变量和静态常量等静态数据,在程序运行期间,数据段的大小固定不变,但其内容可以被修改。按照变量是否被初始化,数据段可分为已初始化数据段和未初始化数据段。

2 不在类中的static

2.1 全局静态变量:

在所有函数外部定义的变量称之为全局变量,作用域默认是整个程序,也就是所有的源文件包括.cpp和.h文件。而当static修饰全局变量时候,变量的存储区域在全局数据区的静态常量区。变量的作用域由整个程序变为当前文件。文件作用域的声明在缺省的情况下为external链接属性,如定义全局变量 in a = 1,a的链接属性为external,而加上static会修改变量的缺省链接属性,为internal。internal不能为其他文件所访问。

2.2 局部静态变量

定义在函数内部的变量成为局部变量,非局部静态变量的作用域仅限于函数内部,离开该函数后就是无效的。当static修饰局部变量时,变量的存储区域由栈变为静态常量区。变量的生命周期由局部调用结束变为程序运行结束。

函数调用开辟栈帧,函数中的局部变量在栈上分配存储空间,当函数执行完毕,函数栈帧销毁,栈空间由系统回收。而在static修饰函数局部变量的时候,其修饰的局部变量只执行初始化一次,延长了局部变量的生命周期,直到程序运行结束以后才释放,但不改变作用域。

2.3 静态函数

普通的函数作用域与全局变量一样都是整个程序。

当static修饰函数的时候,函数的作用域由整个程序变成当前文件。

3 在类中的static

3.1 类的静态成员

在类内成员变量的声明前加上关键字static,则该数据成员就是类内的静态数据成员。静态成员可以在多个对象之间进行数据共享,因为静态数据保存在数据段中,因此静态成员变量一共就一份,无论这个类被定义了多少次,静态成员变量都只分配一次内存。是由改类的所有对象共享访问的。(数据段中的变量都有默认的初始值,堆区栈区的变量默认值都是垃圾值。)

所有类都共享,是因为单独的在数据段中开辟的内存,因此不占用对象的内存。如下代码,类A的大小和类B的大小是一样的,虽然类A中多定义了一个static。

#include<iostream>
using namespace std;class A
{
public:int a1;static int a2;
};
class B
{
public:int b1;
};
int main()
{A a;B b;cout << sizeof(a) << endl;cout << sizeof(b) << endl;return 0;
}result:
4
4

因为static变量开辟在别的区,因此在没有类的实例的时候,静态成员变量就已经存在了,就可以操作他。因此,就可以不用声明对象,直接对类中的静态成员变量进行赋值,如下代码,最终结果可以直接输出,很神奇。

#include<iostream>
using namespace std;class A
{
public:int a1 = 0;static int a2;
};
class B
{
public:int b1;
};
int A::a2 = 2;
int main()
{cout << A::a2;return 0;
}

上述代码中,其实还有一个大坑,不知道看到了没,就是关于静态成员变量的初始化。int A::a2这一行,这个是静态的初始化方式,是在加载时完成的初始化,即在main函数执行前由运行时调用响应的代码进行初始化的。还有一种方法叫动态初始化,代码如下,记住,静态成员必须初始化必须初始化必须初始化,并且只能在类外只能在类外只能在类外,就是 int A::a2这个。

int A::a2;
int main()
{A::a2 = 2;cout << A::a2;return 0;
}

3.2 类的静态成员函数

声明为static的类成员函数成为类的静态成员函数。静态成员函数没有this指针,因为类的静态成员函数是属于整个类而非类的对象,所以没有this指针,这就导致了只能访问类的静态数据和静态成员函数。并且不能将静态成员函数定义为虚函数。

3.3 只在cpp内有效的全局变量

3.4 只在cpp内有效的全局函数

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

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

相关文章

C语言中原码,反码,补码与移位操作符

前言 我们现在学习一下C语言中移位操作符的使用&#xff0c;与原码、补码、反码的概念与使用&#xff0c;在原码补码反码中&#xff0c;正整数三个都相同&#xff0c;负数的话我们在下面详细讲解。 原码反码补码的概念&#xff1a;他们是整数的二进制表示的三种方式 正整数 在正…

如何降低漏测, 避免上线后出bug,6年测试心得分享

一、漏测原因总结 &#xff08;1&#xff09;需求评审质量低&#xff0c;需求设计简单、只是简单描述功能&#xff0c;功能逻辑较少   &#xff08;2&#xff09;需求变更频繁   &#xff08;3&#xff09;缺少需求分解&#xff08;sql 文档、用例设计&#xff09;   &…

爬取东方财富股票代码

我们打开东方财富网站&#xff1a;http://quote.eastmoney.com/stocklist.html 假如懒得爬&#xff0c;也可以用现成的股票数据源&#xff1a;https://stockapi.com.cn 这展示了所有股票信息&#xff0c;不过需要我们分页去爬取 我们可以查询具体的html代码&#xff1a; <…

考研数学|《1800》《1000》《660》《880》如何搭配❓

这几本书都是不同阶段对应的习题册 我觉得最舒服的使用就是方式就是基础阶段用《1800题基础部分》然后强化阶段主要刷《880题》并且强化阶段带着刷《660题》 上面是我的使用方式。之所以没有刷《1000题》是因为这本习题册的难度对我来说还是太大了&#xff0c;并且计算量很大…

LeetCode 每日一题 Day 123-136

1379. 找出克隆二叉树中的相同节点 给你两棵二叉树&#xff0c;原始树 original 和克隆树 cloned&#xff0c;以及一个位于原始树 original 中的目标节点 target。 其中&#xff0c;克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中&#xff0c;与 tar…

【Python基础】—— scipy.spatial.KDTree、matplotlib.pyplot、imageio

scipy.spatial参考博客&#xff1a;Python点云处理——建立KDtree 1 KDtree算法原理 KDtree构建出了一种类似于二叉树的树形数据存储结构&#xff0c;每一层都对应原始数据中相应的维度&#xff0c;以K层为一个循环&#xff0c;因此被称为KDtree。 每一层的左右子树的划分依据…

PLC扩展更自由,钡铼IOy系列模块实现DI/DO/AI/AO任意组合

随着工业自动化的不断发展&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为工业控制领域的核心设备&#xff0c;扮演着至关重要的角色。而钡铼IOy系列模块作为PLC的重要扩展设备&#xff0c;不仅实现了DI&#xff08;数字输入&#xff09;、DO&#xff08;数字输出…

Noisy Student(CVPR 2020)论文解读

paper&#xff1a;Self-training with Noisy Student improves ImageNet classification official implementation&#xff1a;https://github.com/google-research/noisystudent 本文的创新点 本文提出了一种新的半监督方法Noisy Student Training&#xff0c;主要包括三步…

L2-3 完全二叉树的层序遍历

完全二叉树的层序遍历 一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是完美二叉树。对于深度为 D 的&#xff0c;有 N 个结点的二叉树&#xff0c;若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点&#xff0c;这样的树就是完全…

防止企业数据泄密的四种有效措施

防止企业数据泄密的四种有效措施 泄密大案每天都在上演&#xff0c;受害者既有几十人的小型企业&#xff0c;也有上万人的世界500强&#xff0c;为什么这些企业都难逃数据泄露的噩梦呢&#xff1f;我们应该采取什么措施来防止信息泄密呢&#xff1f; 首先我们来看看数据泄密的…

Slf4j+Log4j简单使用

Slf4jLog4j简单使用 文章目录 Slf4jLog4j简单使用一、引入依赖二、配置 log4j2.xml2.1 配置结构2.2 配置文件 三、使用四、使用MDC完成日志ID4.1 程序入口处4.2 配置文件配置打印4.3 多线程日志ID传递配置 五. 官网 一、引入依赖 <dependencies><dependency><g…

C++项目 -- 负载均衡OJ(一)comm

C项目 – 负载均衡OJ&#xff08;一&#xff09;comm 文章目录 C项目 -- 负载均衡OJ&#xff08;一&#xff09;comm一、项目宏观结构1.项目功能2.项目结构 二、comm公共模块1.util.hpp2.log.hpp 一、项目宏观结构 1.项目功能 本项目的功能为一个在线的OJ&#xff0c;实现类似…