c/c++ static
定义
- 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main
函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。 - 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命名空间里的函数重名,可以将函数定位为
static。 - 修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。
- 修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在 static 函数内不能访问非静态成员。
作用
- 静态成员变量
静态成员变量是属于类本身的变量,而不是某个具体对象的变量。它只在类中有一份内存拷贝,所有类的对象共享这份内存。
- 静态成员变量存储在静态存储区,而不是对象的内存中。
- 所有对象共享一个静态成员变量的拷贝,无论创建多少个对象。
- 静态成员变量在类外进行定义和初始化,且不能在类内初始化(C++17 之后可以使用 inline 初始化)。
- 静态成员变量在程序开始时分配内存,直到程序结束才释放。 它的生命周期贯穿整个程序运行期间。
- 可以通过类名直接访问,也可以通过对象访问(推荐使用类名访问以强调静态成员的性质)
class MyClass {
public:// 静态成员变量声明static int counter; // 静态成员函数static void Increment() {counter++;}// 获取静态变量值static int GetCounter() {return counter;}
};
使用:// 通过类名访问MyClass::Increment(); // 输出:Counter: 1cout << "Counter: " << MyClass::GetCounter() << endl;// 通过对象访问(不推荐)MyClass obj1;obj1.Increment();// 输出:Counter: 2cout << "Counter: " << MyClass::GetCounter() << endl; MyClass obj2;obj2.Increment();// 输出:Counter: 3cout << "Counter: " << MyClass::GetCounter() << endl;
- 静态成员函数
在 C++ 中,静态成员函数(static member function)是属于类本身而不是某个具体对象的成员函数。它使用 static 关键字进行声明,可以在没有创建类的实例时通过类名直接调用。
class MyClass
{
public:// 使用关键字 static 声明静态成员函数static void print();
};// 在类外定义静态成员函数时,不需要再次使用 static 关键字:
void MyClass::print() {std::cout << "This is a static member function." << std::endl;
}调用:静态成员函数可以通过类名或对象调用,但推荐通过类名调用// 通过类名调用MyClass::print(); // 通过对象调用MyClass obj;obj.print();
- 静态全局变量
使用 static 修饰的全局变量,只可以使其在声明所在的文件内可见,这样可以避免与其他文件中相同名称的变量产生冲突
static int globalCount;
- 静态普通函数
需要 static 修饰的函数成为静态函数,这种函数只能在声明所在的文件内部调用,无法被其他文件直接调用,这对一些 辅助函数或者实用函数,限制在特定的文件范围内非常有用
static int add(const int& a,const int & b)
{return a + b;
}
- 静态局部变量
在一个函数内部使用 static 的变量,称为局部静态变量,与普通的局部变量不同,局部静态变量在函数调用结束后不会被销毁而是保持其值与存在。
如果你想重复使用一个变量由不想将它声明为全局变量,就可以将它声明为静态局部变量
int getCount()
{static int count = 0;count++;return count;
}
逆向 C++ static
class MyClass {public:MyClass(){number = 0x111111;counter = 0x222222;}public:static int counter;int number;void printNumber(){std::cout << number << std::endl;}static void printCounter(){std::cout << counter << std::endl;}
}
调用:
MyClass obj;
进入构造函数:
00007FF6A94610B3 | 48:8D4C24 20 | lea rcx,qword ptr ss:[rsp+20]
;public: __cdecl MyClass::MyClass(void)
00007FF6A94610B8 | E8 43FFFFFF |call 0x00007FF6A9461000 构造函数中看 静态成员变量 counter 和 成员变量 number 00007FF6A9461000 <te | 48:894C24 08 | mov qword ptr ss:[rsp+8],rcx
00007FF6A9461005 | 48:8B4424 08 | mov rax,qword ptr ss:[rsp+8]
; 成员变量number 赋值
00007FF6A946100A | C700 11111100 | mov dword ptr ds:[rax],111111
; static int MyClass::counter 静态成员变量赋值:
00007FF6A9461010 | C705 1A360000 22222200 | mov dword ptr ds:[0x00007FF6A9464634], 0x222222
00007FF6A946101A | 48:8B4424 08 | mov rax,qword ptr ss:[rsp+8]
00007FF6A946101F | C3 | ret 成员函数调用:
obj.printNumber();
00007FF6A94610BD | 48:8D4C24 20 | lea rcx,qword ptr ss:[rsp+20]
; void __cdecl MyClass::printNumber(void)
00007FF6A94610C2 | E8 59FFFFFF | call 0x00007FF6A9461020-------------------- printNumber --------------------
00007FF6A9461020 <te | 48:894C24 08 | mov qword ptr ss:[rsp+8],rcx
00007FF6A9461025 | 48:83EC 28 | sub rsp,28
00007FF6A9461029 | 48:8B4424 30 | mov rax,qword ptr ss:[rsp+30]
; edx = number = 0x11111
00007FF6A946102E | 8B10 | mov edx,dword ptr ds:[rax]
; 下面是调用 std::cout 打印输出
00007FF6A9461030 | 48:8B0D 69100000 | mov rcx, qword ptr ds:[0x00007FF6A94620A0]
00007FF6A9461037 | FF15 6B100000 | call qword ptr ds:[0x00007FF6A94620A8]
00007FF6A946103D | 48:8D15 9C000000 | lea rdx, ds:[0x00007FF6A94610E0]
00007FF6A9461044 | 48:8BC8 | mov rcx,rax
00007FF6A9461047 | FF15 33100000 | call qword ptr ds:[0x00007FF6A9462080]
00007FF6A946104D | 48:83C4 28 | add rsp,28
00007FF6A9461051 | C3 | ret 静态成员函数调用:obj.printCounter();call 0x00007FF6A9461060-------------------- printCounter --------------------
00007FF6A9461060 <te | 48:83EC 28 | sub rsp,28
; 静态成员变量 edx = 0x222222
00007FF6A9461064 | 8B15 CA350000 | mov edx, dword ptr ds:[0x00007FF6A9464634]
; std::cout 输出
00007FF6A946106A | 48:8B0D 2F100000 | mov rcx, qword ptr ds:[0x00007FF6A94620A0]
00007FF6A9461071 | FF15 31100000 | call qword ptr ds:[0x00007FF6A94620A8]
00007FF6A9461077 | 48:8D15 62000000 | lea rdx, ds:[0x00007FF6A94610E0]
00007FF6A946107E | 48:8BC8 | mov rcx,rax
00007FF6A9461081 | FF15 F90F0000 | call qword ptr ds:[0x00007FF6A9462080]
00007FF6A9461087 | 48:83C4 28 | add rsp,28
00007FF6A946108B | C3 | ret
相关文章:
c/c++ static
定义 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。修饰普通函数,表明函数的作…...
C#中System.Text.Json:从入门到精通的实用指南
一、引言 在当今数字化时代,数据的高效交换与处理成为软件开发的核心环节。JSON(JavaScript Object Notation)凭借其简洁、轻量且易于读写的特性,已然成为数据交换领域的中流砥柱。无论是前后端数据交互,还是配置文件…...
内存故障原因与诊断(Reasons and Diagnosis of Memory Failure)
内存故障原因与诊断 您是否曾遇到过电脑无法启动、黑屏、死机,或者系统卡顿的情况?这些问题看起来很复杂,实际上大多数都是内存故障引起的。内存是电脑的核心组成部分之一,任何小东西问题都可能导致系统死机,严重时甚…...
[操作系统] 进程状态详解
在操作系统中,进程是程序执行的基本单位,操作系统负责管理进程的生命周期。为了高效地管理进程,操作系统通过定义不同的进程状态来表示进程在不同时间点的行为。本文将详细介绍常见的进程状态及其相互之间的转换过程。 进程状态概述 在kerne…...
[论文阅读] (36)CS22 MPSAutodetect:基于自编码器的恶意Powershell脚本检测模型
《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座,并分享给大家,希望您喜欢。由于作者的英文水平和学术能力不高,需要不断提升,所以还请大家批评指正,非常欢迎大家给我留言评论,学术路上期…...
【Maui】下拉框的实现,绑定键值对
文章目录 前言一、问题描述二、解决方案三、软件开发(源码)3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言 .NET 多平台应用 UI (.NET MA…...
Oracle 深入学习 Part 14:Managing Password Security and Resources(管理密码安全性和资源)
Profiles Profile 是一个以名称标识的集合,用于管理 密码 和 资源限制。 每个用户都对应一个profiles,可以通过 CREATE USER 或 ALTER USER 命令分配给用户。 Profiles 可以启用或禁用。 Profiles 可以关联到默认的 DEFAULT Profile。 密码管理&…...
C语言:位段
位段的内存分配: 1. 位段的成员可以是 int unsigned int signed int 或者是char (属于整形家族)类型 2. 位段的空间上是按照需要以4个字节( 类型 int )或者1个字节( char )的方式来开辟的。 3. 位段涉及…...
MPLS VPN 原理与配置
一.简介 MPLS,称之为多协议标签交换,在九十年代中期被提出来,用于解决传统IP报文依赖查表转发而产生的瓶颈,现多用于VPN技术,MPLS报头封装在数据链路层之上,网络层之下。本文为结合了华为技术和新华三技术…...
稳定的通信桥梁,CCLINKIE转ModbusTCP网关实现AGV运输的光速效应
三菱PLC与AGV机器人搬运车通过稳联技术协议转换网关建立通信 一、现场情况概述 - 三菱PLC:使用CC-Link IE协议进行通信。 - AGV机器人搬运车:使用Modbus TCP协议进行通信。 - 协议转换网关:使用稳联技术的协议转换网关将PLC和AGV连接…...
Leetcode 3428. Maximum and Minimum Sums of at Most Size K Subsequences
Leetcode 3428. Maximum and Minimum Sums of at Most Size K Subsequences 1. 解题思路2. 代码实现 题目链接:3428. Maximum and Minimum Sums of at Most Size K Subsequences 1. 解题思路 这一题不需要连续性,因此我们就是考虑取得子串长度为别为1…...
第2章:Python TDD构建Dollar类基础
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
【算法学习笔记】34:扩展欧几里得算法
裴蜀定理 描述 对于任意正整数 a a a、 b b b,一定存在整数系数 x x x, y y y,使得: a x b y g c d ( a , b ) ax by gcd(a, b) axbygcd(a,b) 并且 g c d ( a , b ) gcd(a, b) gcd(a,b)是对于任意的系数 x x x和 y y y放在…...
云原生周刊:K8s 生产环境架构设计及成本分析
开源项目推荐 KubeZoneNet KubeZoneNet 旨在帮助监控和优化 Kubernetes 集群中的跨可用区(Cross-Zone)网络流量。这个项目提供了一种简便的方式来跟踪和分析 Kubernetes 集群中跨不同可用区的通信,帮助用户优化集群的网络架构、提高资源利用…...
WGAN - 瓦萨斯坦生成对抗网络
1. 背景与问题 生成对抗网络(Generative Adversarial Networks, GANs)是由Ian Goodfellow等人于2014年提出的一种深度学习模型。它包括两个主要部分:生成器(Generator)和判别器(Discriminator)…...
海量数据的处理
一般来说都是针对数据量特别大,内存有限制的。 第一类:topk问题 比如,在海量数据中找前50大的数据怎么办? 方法一:使用小顶堆,用小顶堆维护这50个元素,当有新元素到来时,直接与堆…...
区块链的数学基础:核心原理与应用解析
引言 区块链技术作为分布式账本系统,成功地解决了传统中心化系统中的信任问题。其背后隐藏着复杂而精妙的数学原理,包括密码学、哈希函数、数字签名、椭圆曲线、零知识证明等。这些数学工具不仅为区块链提供了安全保障,也为智能合约和去中心…...
1.5 GPT 模型家族全解析:从 GPT-1 到 GPT-4 的演进与创新
GPT 模型家族全解析:从 GPT-1 到 GPT-4 的演进与创新 随着人工智能技术的飞速发展,GPT(Generative Pre-trained Transformer)模型家族已经成为了现代自然语言处理(NLP)领域的标杆。从初代的 GPT-1 到最新的 GPT-4,每一代模型的发布都标志着人工智能技术的一个飞跃,并推…...
自动驾驶之DriveMM: All-in-One Large Multimodal Model for Autonomous Driving
1. 写在前面 工作之后,主要从事于偏工程比较多的内容, 很少有机会读论文了,但2025年,由于之前有些算法的背景, 后面可能会接触一些多模态大模型相关的工作,所以又调头有点往算法的方向偏移, 而算法呢,很重要的一点就是阅读论文。2025年,再拾起论文这块的工作。 今天…...
Spring Boot 配置(官网文档解读)
目录 摘要 Spring Boot 配置加载顺序 配置文件加载顺序 Spring Boot 配置加载方式 Value Value 注解简单示例 ConfigurationProperties 启动 ConfigurationProperties ConfigurationProperties 验证 ConfigurationProperties 与 Value 对比 Autowired Autowired 自…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
