当前位置: 首页 > news >正文

c++ static关键字的详细用法和作用

一.前言

在讲static之前,先明确两个关键术语:

· 生命周期:变量从创建到销毁的时间段(全局变量生命周期是整个程序运行期,局部变量是所在函数执行期);

· 作用域:变量 / 函数能被访问的范围(全局作用域 = 整个程序,局部作用域 = 函数 / 代码块内,类作用域 = 类内部)。

static的核心作用就是:延长生命周期、缩小作用域(不同场景下侧重点不同)。

二.static 的 4 个核心使用场景(按常用度排序)

场景 1:修饰局部变量(函数内的 static 变量)

作用:

生命周期:从 “函数执行期” 变为 “整个程序运行期”(只初始化 1 次,程序结束才销毁);

作用域:仍局限在所在函数内(外部无法访问)。

代码示例(最经典的计数器):

#include <iostream> using namespace std; void countCall() { // static局部变量:只初始化1次,下次调用直接用上次的值 static int count = 0; count++; cout << "函数被调用了:" << count << "次" << endl; } int main() { countCall(); // 输出:函数被调用了:1次 countCall(); // 输出:函数被调用了:2次 countCall(); // 输出:函数被调用了:3次 return 0; }

关键说明:

如果去掉static,count每次调用都会重置为 0,输出永远是 1;

static局部变量的初始化在程序启动时完成(而非函数第一次调用时),且只执行 1 次;

存储位置:从 “栈区” 移到 “静态存储区”(全局变量也存在这里)。

场景 2:修饰全局变量 / 函数(文件级的 static)

作用:

作用域:从 “整个程序(所有源文件)” 缩小为 “当前源文件”(其他文件无法访问);

生命周期:仍为整个程序运行期(无变化)。

为什么需要?

全局变量 / 函数默认是 “外部链接”(extern),其他源文件通过extern就能访问,容易导致命名冲突;static把它变成 “内部链接”,仅限当前文件使用,避免冲突。

代码示例:

// file1.cpp #include <iostream> using namespace std; // static全局变量:仅限file1.cpp访问 static int global_num = 100; // static函数:仅限file1.cpp访问 static void printNum() { cout << "global_num: " << global_num << endl; } void test() { printNum(); // 合法:同一文件内可访问 }
// file2.cpp #include <iostream> using namespace std; // 错误:无法访问file1.cpp中的static全局变量 extern int global_num; // 错误:无法访问file1.cpp中的static函数 extern void printNum(); int main() { // 编译报错:undefined reference to `global_num' cout << global_num << endl; // 编译报错:undefined reference to `printNum()' printNum(); return 0; }

场景 3:修饰类的成员变量(静态成员变量)

作用:

属于类本身,而非类的某个对象(所有对象共享同一个静态成员变量);

生命周期:整个程序运行期;

必须在类外初始化(因为不属于任何对象,不能在构造函数里初始化)。

代码示例:

#include <iostream> using namespace std; class Student { public: // 静态成员变量:统计学生总数(所有对象共享) static int total_num; string name; // 构造函数:创建对象时总数+1 Student(string n) : name(n) { total_num++; } }; // 静态成员变量必须在类外初始化(关键!) int Student::total_num = 0; int main() { Student s1("张三"); Student s2("李四"); Student s3("王五"); // 两种访问方式:类名::变量 或 对象.变量(推荐用类名) cout << "学生总数:" << Student::total_num << endl; // 输出3 cout << "s1对应的总数:" << s1.total_num << endl; // 输出3 return 0; }

场景 4:修饰类的成员函数(静态成员函数)

作用:

属于类本身,而非对象,只能访问静态成员变量 / 函数(不能访问非静态成员,因为没有 this 指针);

可以直接通过 “类名::函数名” 调用,无需创建对象。

代码示例:

#include <iostream> using namespace std; class Student { public: static int total_num; // 静态成员变量 string name; Student(string n) : name(n) { total_num++; } // 静态成员函数:获取学生总数(只能访问静态成员) static int getTotalNum() { // 错误:不能访问非静态成员name(没有this指针) // cout << name << endl; return total_num; } }; int Student::total_num = 0; // 初始化静态成员变量 int main() { // 无需创建对象,直接通过类名调用静态函数 cout << "初始总数:" << Student::getTotalNum() << endl; // 输出0 Student s1("张三"); // 也可以通过对象调用(不推荐) cout << "当前总数:" << s1.getTotalNum() << endl; // 输出1 return 0; }
http://www.jsqmd.com/news/461723/

相关文章:

  • Spring的IOC详解
  • 2026年苏州青少年篮球培训怎么选?这几家TOP机构值得关注!
  • Claude Code 隐藏功能大全:90%的人不知道这些
  • 150 万人被偷家之后,我翻了翻自己的 API Key 管理,冷汗直流
  • 帮朋友拆了一个机械臂问题,从误解到最优解
  • FFMPEG网络推流
  • 技术落地解析:深圳市兴通物联俄罗斯诚信标签条码比对系统,提升对俄出口合规效率
  • 2026年叔丁醇钾选购,江苏天泽新材料费用合理值得考虑 - myqiye
  • 跑步耳机挂脖好还是无线好?2026最适合跑步用的耳机真实体验分享
  • Python保护类内部私有变量,不允许外部类访问的一种简单实现
  • 口碑好的多肽修饰厂家2026年排行榜,哪家服务更贴心 - 工业推荐榜
  • OpenClaw本地私有化部署教程
  • 进口阀门市场发展趋势与工业应用解析
  • 矩阵论考题——答案
  • 和信通卡回收折扣对比2026,畅回收平台折脱颖而出 - 畅回收小程序
  • PbootCMS附件上传报错UNKNOW: Code: 8192; Desc: stripos()
  • 收藏!小白程序员必看:手把手教你玩转大模型上下文工程,提升代理智能
  • 亚马逊合规趋严,海外仓如何破解物流卡点,实现高效履约?
  • 2026年金华地区好用的日语高考培训学校排名 - mypinpai
  • docker安装nacos
  • 【金蝶云星空】如何给科目挂上核算维度
  • 本地ubuntu服务器上部署openclaw完整教程(详细图文)
  • 苏州小区停车场道闸系统推荐:智慧停车系统怎么选? - 品牌观察员小捷
  • 2026年全国气流粉碎机哪家好?实力筑牢精度与服务壁垒 一站式解决方案适配各类场景 - 深度智识库
  • 2026.03.10学习记录(游戏)
  • 【量化工具推荐】2026年国内期货量化软件年度排行
  • 2026年靠谱的全屋净水系统品牌推荐:全屋净水安装/全屋净水过滤系统优质供应商推荐参考 - 行业平台推荐
  • 2026年热门的塑料管夹厂家推荐:铝合金管夹/不锈钢管夹/轻型塑料管夹厂家实力与用户口碑参考 - 行业平台推荐
  • 抗老眼霜怎么选?2026抗皱淡黑消肿TOP5,成分效果性价比拉满 - 速递信息
  • 2026最强AI论文生成工具Top5_multimodal+global thought chain