c++中static的用法
static是c++中的一个关键字,其共有四种用法,下面分开进行介绍。
一、静态局部变量——在函数内部声明的静态变量
使用static在函数内部修饰局部变量,可以将变量声明为静态局部变量。即使函数结束,静态局部变量的值也会保留,用于记录历史信息。
1 | |
当多次调用count()函数时,counter变量的值会累加,而不是每次都从0开始。
静态局部变量的性质
- 存储位置
- 静态局部变量存放在静态存储区(全局/静态区),而不是栈。
- 与全局变量存储位置相同
- 生命周期
- 在程序启动时或函数首次执行到声明处时初始化。
- 一直存活到程序结束,不会因为函数退出而销毁。
- 与普通局部变量不同,普通局部变量每次函数调用时都会重新创建和销毁。
- 作用域
- 作用域仍然是局部的,只能在声明它的函数或代码块中访问。
- 但不同调用之间共享同一份数据。
- 初始化规则
- 如果显式初始化,只会在第一次执行到定义处时初始化一次。
- 如果没有显式初始化,则会被零初始化(基本类型初始化为0,指针类型初始化为nullptr)。
- 线程安全(C++11开始)
- C++11保证了静态局部变量的初始化是线程安全的。
- 多个线程同时进入时,只有一个线程会执行初始化,其他线程阻塞等待。
二、静态全局变量——在函数外部声明的静态变量
其作用范围局限于声明它的文件内,通常用于在一个文件内共享信息,但防止其他文件访问。
1 | |
该counter只能在file1.cpp中访问,其他的.cpp文件是无法访问的。
静态全局变量的性质
- 存储位置
- 与普通全局变量一样,存放在静态存储区。
- 作用域
- 普通全局变量->默认有外部链接,可以被其他文件使用extern引用。
- 静态全局变量->具有内部链接,只在定义它的源文件内可见,不能被其他文件访问。
- 初始化
- 只会初始化一次。
- 没有显示初始化时,编译器会自动初始化为0。
- 生命周期
- 和程序运行期一致。
使用场景
- 避免全局变量命名冲突
- 如果在多个源文件内都定义了相同名字的全局变量,可能会导致链接错误;使用static限制在文件内部,可以避免冲突。
- 实现文件内共享的状态
- 当一个变量需要在整个文件内多处使用,但不想暴露给其他文件时,可以使用静态全局变量。
三、静态成员变量——类中的静态成员变量
其是类中所有对象共有的。静态成员变量在所有对象中有且仅有一个副本,通常用于所有对象需要共享同一个变量的时候。
1 | |
C++17开始,若在类内声明时加上inline,就可以直接在类内初始化,而不必在类外再定义
1 | |
静态成员变量的性质
- 存储位置
- 存放在静态存储区。
- 作用域
- 作用域属于类作用域
- 生命周期
- 与程序运行期一致。
- 初始化
- 类内只是声明,不能直接分配存储空间(C++17之前)。
- 必须在类外定义一次,否贼会链接错误。
- 如果是
const static整形或枚举,可以在类内直接初始化。
使用场景
- 统计类对象的数量
- 全局共享资源
- 如数据库连接池、日志开关,只需要一份全局数据,但封装在类中更合理。
- 与静态成员函数配合
- 静态成员函数不能访问普通成员变量,但可以访问静态成员变量。
四、静态成员函数——类中的静态成员函数
其也是类中所有对象所共有的。静态成员函数只能访问静态成员数据,其他静态成员函数和类外部的其他函数。
1 | |
静态成员函数的性质
- 不依赖对象存在
- 没有this指针
- 在静态成员函数内部不能访问非静态成员变量,也不能调用非静态成员函数。
- 作用域属于类
- 生命周期
- 整个程序运行期。
使用场景
- 操作静态成员变量
- 作为工具函数
- 可以写一些与类相关,但不依赖对象的函数。
1 | |
参考
c++中static的用法
https://delta0406.github.io/2025/09/11/技术/语言/CPP/c-中static的用法/