c++ static(详解)

news2024/9/20 1:16:55

C++中,static关键字用于定义具有静态存储持续时间的变量或方法。它在不同上下文中有不同的含义,通常与变量的存储方式和作用域相关。static的主要作用是控制变量或函数的可见性和生命周期。

可以通过一个生活中的场景来形象化static的作用:

场景:

假设你是一位图书馆管理员,负责管理图书馆中每个人的借书记录。每次有新成员登记时,你都为他们创建一个新的借书账户,并记录他们借的书。但图书馆有一个总借书数的统计,也就是说,不管有多少个会员借书,所有人的借书数量都会加在一起,形成一个全馆的总借书数。

静态变量的作用:

  • 借书账户的个人记录:每个会员都有自己借书的记录(类似于类的普通成员变量),每个人只能看到自己借了几本书。
  • 图书馆的总借书数:图书馆有一个总借书数的统计,这个数字对所有会员来说是共享的(类似于static成员变量),每个会员借了一本书后,这个总数都会增加。

对应到C++代码:

#include <iostream>

using namespace std;

class LibraryMember{
public:
    int personalBorrowedBooks = 0; //个人借书记录

    static int totalBorrowedBooks; //总借书数(所有人共享)

    void borrowBook(){
        personalBorrowedBooks++; //总借书数增加
        totalBorrowedBooks++; //总借书数增加
    }
    void showBorrowInfo(){
        cout <<"You have borrowed " << personalBorrowedBooks << " books." << endl;
        cout <<"The liberary has loand out " << totalBorrowedBooks << " book in total." << endl;
    }

};

//初始化静态成员变量
int LibraryMember::totalBorrowedBooks = 0;

int main(){

    LibraryMember member1;
    LibraryMember member2;

    member1.borrowBook();  // member1借了1本书
    member2.borrowBook();  // member2借了1本书
    member1.borrowBook();  // member1又借了1本书

    cout << "memeber1 Info " << endl;
    member1.showBorrowInfo() ;  // 显示member1的信息
    cout << "memeber2 Info " << endl;
    member2.showBorrowInfo();  // 显示member2的信息

    return 0;
}

输出结果:

memeber1 Info 
You have borrowed 2 books.
The liberary has loand out 3 book in total.
memeber2 Info 
You have borrowed 1 books.
The liberary has loand out 3 book in total.

分析:

  1. 个人借书记录(非静态成员变量):每个LibraryMember对象有自己独立的借书记录。member1借了2本书,而member2借了1本书,他们各自的记录是独立的。
  2. 总借书数(静态成员变量):所有成员共享一个总借书数,不管是哪个成员借了书,这个总借书数都会增加。

静态的现实意义:

static 就像图书馆的总借书统计,它不会因为某个会员的加入或离开而被重新设置或注销,始终保持一个全局的、共享的状态。这类似于生活中我们对一些全局、共享数据的统计与追踪,所有人都可以贡献,但数据是统一维护的。

1. 静态成员变量

静态成员变量(类的静态变量)属于整个类,而不是某个具体的对象。它们在所有对象中共享,也就是说,不管创建了多少个类对象,静态成员变量在内存中只有一份,且对所有对象都是共用的。

  • 作用:用于存储类的全局状态,所有对象共享该状态。
class MyClass {
public:
    static int staticVar;
    MyClass() { staticVar++; }  // 每次创建对象时都会递增
};

int MyClass::staticVar = 0;  // 静态变量需要在类外初始化

int main() {
    MyClass obj1;
    MyClass obj2;
    cout << MyClass::staticVar;  // 输出 2
}

2. 静态成员函数

静态成员函数和静态成员变量类似,它们属于整个类,而不是某个对象。静态成员函数只能访问静态成员变量,不能访问非静态成员变量,因为非静态成员变量依赖于具体的对象实例。

  • 作用:用于不依赖对象的功能实现,比如操作静态成员变量。
class MyClass {
public:
    static int staticVar;
    static void printStaticVar() {
        cout << staticVar << endl;  // 可以访问静态变量
    }
};

int MyClass::staticVar = 0;

int main() {
    MyClass::printStaticVar();  // 直接通过类名调用静态函数
}

3. 静态局部变量

在函数内部,static 局部变量的生命周期贯穿整个程序的执行,而不仅仅是在函数调用期间。它在函数第一次被调用时初始化,并在程序的整个生命周期内保持其值。

  • 作用:用于需要在函数多次调用时保持其状态的场景。
void countCalls() {
    static int count = 0;  // 只初始化一次
    count++;
    cout << "This function has been called " << count << " times" << endl;
}

int main() {
    countCalls();  // 输出 1
    countCalls();  // 输出 2
    countCalls();  // 输出 3
}

4. 静态全局变量

static 修饰的全局变量(在函数或类外定义)只能在定义它的文件中访问,无法被其他文件访问。这是一种用于控制链接的方式,通常用于实现模块间的数据隔离,防止名称冲突。

  • 作用:用于在一个源文件中定义只对该文件可见的变量。
static int fileVar = 0;  // 只能在当前文件中使用

5. 静态函数(文件作用域)

类似于静态全局变量,static 修饰的函数只能在定义它的文件中使用。这在大型项目中非常有用,因为它可以防止不同文件中的函数名冲突。

  • 作用:用于限制函数的可见性,使其仅在定义的文件中可用。
static void helperFunction() {
    // 只能在当前文件中调用
}

6. 使用场景总结

  • 共享类成员:静态成员变量和静态成员函数在类的不同实例之间共享数据。
  • 维护函数状态:静态局部变量用于在函数调用之间保持状态。
  • 文件级作用域:静态全局变量和静态函数用于实现文件内的变量和函数封装,避免命名冲突。
  • 效率提升:静态成员函数可以在不创建对象的情况下直接调用,减少对象的开销。

static 在C++中用于控制变量或函数的生命周期作用域,在代码优化、模块化设计等方面发挥着重要作用。

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

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

相关文章

实战17-NavBar+Vip布局

NavBar.ets import { PADDING } from ../../constants/size import rvp from ../../utils/resposive/rvIndexComponent export default struct NavBar {StorageProp(topHeight) topHeight: number 0;build() {Row() {Row({ space: rvp(6) }) {Text(请选择地址).fontSize(rvp(1…

Java基础笔记1】Java基础语法

目录 一、Java简介 二、JDK和Java初体验 三、配置环境变量 四、IDEA快捷键 五、Java语法基础 1. 注释 2. 字面量 3. 变量 4. 关键字和标识符 5. 变量详解 a. 数值数据在计算机中的存储​编辑 b. 文本、图片、音频等数据在计算机中的存储 c. 八进制和十六进制 6. 数据类型 a. …

【LabVIEW】事件结构的用法

本篇文章记录我学习LabVIEW的事件结构用法&#xff0c;希望我的分享对你有所帮助&#xff01; 目录 一、案例说明 1、 LabVIEW实现“YAXBXC的计算” 2、添加事件结构 一、案例说明 在LabVIEW实现“YAXBXC的计算”的基础上&#xff0c;加上事件结构&#xff0c;实现单击一次按…

【读书笔记-《30天自制操作系统》-22】Day23

本篇内容比较简单&#xff0c;集中于显示问题。首先编写了应用程序使用的api_malloc&#xff0c;然后实现了在窗口中画点与画线的API与应用程序。有了窗口显示&#xff0c;还要实现关闭窗口的功能&#xff0c;于是在键盘输入API的基础上实现了按下按键关闭窗口。最后发现用上文…

初学者笔记本电脑玩转大模型系列二:微调谷歌Gemma模型

之前分享了《初学者笔记本电脑玩转大模型系列一&#xff1a;利用ollama跑大模型》&#xff0c;这不&#xff0c;Google发布了Gemma开放模型&#xff0c;同等参数尺寸性能最好的大模型&#xff0c;那么言归正传&#xff0c;如何在笔记本电脑微调Gemma模型呢&#xff1f;我们接下…

阿里云CTO:通义稳居全球最强开源大模型,性能接近GPT-4o

来源&#xff1a;首席数智官 9月19日&#xff0c;在2024杭州云栖大会上&#xff0c;阿里云CTO周靖人表示&#xff0c;阿里云正在围绕AI时代&#xff0c;树立一个AI基础设施的新标准&#xff0c;全面升级从服务器到计算、存储、网络、数据处理、模型训练和推理平台的技术架构体…

Temu应用全球下载量突破7.35亿次!美国占27%,还是主要市场

据了解&#xff0c;随着购物者更多选择Temu作为实惠的在线购物目的地&#xff0c;其月访问量在今年第一季度跃升至5亿次以上&#xff0c;应用下载量也大幅增加。据外媒报道&#xff0c;根据Stocklytics的最新数据&#xff0c;Temu应用程序截至目前的下载量已超过7.35亿次。 最新…

动态线程池(二)

动态线程池 环境搭建 启动Nacos和redis 安装Node-Exporter 安装Prometheus 安装Grafana 源码解析

鸢尾花书实践和知识记录[数学要素3-2乘除]

书的作者 文章目录 算术乘除&#xff1a;先乘除&#xff0c;后加减&#xff0c;括号内先算基本的乘法运算计算阶乘基本除法 向量的乘法&#xff1a;标量乘法&#xff0c;向量内积&#xff0c;逐项积标量乘法向量的内积对于inner和dot的实现方式的探究逐项积dot的计算过程 逐项…

MAC如何获取文件数字签名和进程名称

1、安装需要查看数字签名和进程名称的软件包 2、打开终端命令行(Terminal) 3、查找数字签名 在终端命令行中输入: codesign -dvv 安装的软件路径 2>&1 | grep "Authority=" | head -n 1 | cut -d = -f2”

PDF使用虚拟列表技术做渲染和加载带来的问题

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

JavaFX实现视频播放功能

一、前言 最近使用javaFx写了个简单的视频播放功能&#xff0c;可以实现打开本地视频播放。 二、实现 1.使用jdk8自带的javaFx包实现&#xff0c;首先定义一个类VideoPlayer。 代码如下&#xff1a; import javafx.application.Application; import javafx.application.Platf…

LAN8720A-CP-TR-ABC QFN-24 以太网收发器芯片

功能&#xff1a; 高性能收发器&#xff1a;支持10BASE-T和100BASE-TX标准&#xff0c;能够自动协商最佳速度和双工模式。 小尺寸&#xff1a;是业界尺寸最小的解决方案&#xff0c;适合空间受限的应用场景。 低功耗&#xff1a;功耗比现有的Microchip收发器低40%&#x…

【Unity】URP Rendering总结

unity-urp-rendering 介绍 个人学习总结&#xff0c;不定期更新 仓库 Unity版本&#xff1a;2022.3.42 Unity URP渲染管线下相关的渲染demo和总结 1. GPUInstance 1.1 Graphics.DrawMeshInstanced 1.2 Graphics.DrawMeshInstancedIndirect 1.3 MeshRenderer.SetPropertyBlock…

MTK芯片机型的“工程固件” 红米note9 5G版资源预览 写入以及改写参数相关步骤解析

小米机型:小米5 小米5x 米6 米6x 米8 米9 米10系列 米11系列 米12系列 mix mix2 mix2s mix3 max max2 max3 note3 8se 9se cc9系列 米play 平板系列等分享 红米机型:红米note4 红米note4x 红米note5 红米note6 红米note7 红米note8 红米note8pro 红米s2 红米note7pro 红米…

【C++算法】模拟算法

替换所有的问号 题目链接 替换所有的问号https://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/description/ 算法原理 代码步骤 class Solution { public:string modifyString(string s) {int n s.size();for(int i 0; i < n; i){…

网络药理学:15、草稿暂存区

TCMSP 韦恩图在线网站 https://bioinfogp.cnb.csic.es/tools/venny/index.html String数据库参数详解&#xff1a;https://www.bilibili.com/video/BV1q64y1k7Zf?p16&vd_sourceaed4c634975918b14b7354ec93ce5389 David数据库可以用基因ID或者基因名。 KEGG数据库使用&am…

高效处理NPE!!

相信不少小伙伴已经被java的NPE(Null Pointer Exception)所谓的空指针异常搞的头昏脑涨,有大佬说过“防止 NPE&#xff0c;是程序员的基本修养。”但是修养归修养&#xff0c;也是我们程序员最头疼的问题之一&#xff0c;那么我们今天就要尽可能的利用Java8的新特性 Optional来…

视觉语言大模型模型介绍-CLIP学习

多模态学习领域通过结合图像和文本信息&#xff0c;为各种视觉语言任务提供了强大的支持。图像和文本的结合在人工智能领域具有重要的意义&#xff0c;它使得机器能够更全面地理解人类的交流方式。通过这种结合&#xff0c;模型能够处理包括图像描述、视觉问答、特征提取和图像…

Maya动画基础

Maya动画基础教程&#xff08;完整&#xff09;_哔哩哔哩_bilibili 第一集 动画基础设置 altv播放动画 选择撕下副本 右键---播放预览 第二集 k帧记录物体的空间信息 初始位置清零 删除历史记录 s键key帧 自动记录位置信息 删除帧&#xff0c;按住右键选择delete 按shif…