c++中static的用法

static是c++中的一个关键字,其共有四种用法,下面分开进行介绍。

一、静态局部变量——在函数内部声明的静态变量

使用static在函数内部修饰局部变量,可以将变量声明为静态局部变量。即使函数结束,静态局部变量的值也会保留,用于记录历史信息。

1
2
3
4
5
void count() {
static int counter = 0; // 静态局部变量
counter++;
std::cout << counter << std::endl;
}

当多次调用count()函数时,counter变量的值会累加,而不是每次都从0开始。

静态局部变量的性质

  1. 存储位置
  • 静态局部变量存放在静态存储区(全局/静态区),而不是栈。
  • 与全局变量存储位置相同
  1. 生命周期
  • 在程序启动时或函数首次执行到声明处时初始化。
  • 一直存活到程序结束,不会因为函数退出而销毁。
  • 与普通局部变量不同,普通局部变量每次函数调用时都会重新创建和销毁。
  1. 作用域
  • 作用域仍然是局部的,只能在声明它的函数或代码块中访问。
  • 但不同调用之间共享同一份数据。
  1. 初始化规则
  • 如果显式初始化,只会在第一次执行到定义处时初始化一次。
  • 如果没有显式初始化,则会被零初始化(基本类型初始化为0,指针类型初始化为nullptr)。
  1. 线程安全(C++11开始)
  • C++11保证了静态局部变量的初始化是线程安全的。
  • 多个线程同时进入时,只有一个线程会执行初始化,其他线程阻塞等待。

二、静态全局变量——在函数外部声明的静态变量

其作用范围局限于声明它的文件内,通常用于在一个文件内共享信息,但防止其他文件访问。

1
2
// file1.cpp
static int counter = 0; // 静态全局变量

该counter只能在file1.cpp中访问,其他的.cpp文件是无法访问的。

静态全局变量的性质

  1. 存储位置
  • 与普通全局变量一样,存放在静态存储区。
  1. 作用域
  • 普通全局变量->默认有外部链接,可以被其他文件使用extern引用。
  • 静态全局变量->具有内部链接,只在定义它的源文件内可见,不能被其他文件访问。
  1. 初始化
  • 只会初始化一次。
  • 没有显示初始化时,编译器会自动初始化为0。
  1. 生命周期
  • 和程序运行期一致。

使用场景

  1. 避免全局变量命名冲突
  • 如果在多个源文件内都定义了相同名字的全局变量,可能会导致链接错误;使用static限制在文件内部,可以避免冲突。
  1. 实现文件内共享的状态
  • 当一个变量需要在整个文件内多处使用,但不想暴露给其他文件时,可以使用静态全局变量。

三、静态成员变量——类中的静态成员变量

其是类中所有对象共有的。静态成员变量在所有对象中有且仅有一个副本,通常用于所有对象需要共享同一个变量的时候。

1
2
3
4
5
6
7
8
9
class MyClass {
public:
static int counter; // 静态成员变量
};

// 需要在类定义的外部初始化静态成员变量
int MyClass::counter = 0;

// 所有的 MyClass 对象都会共享同一个 counter 变量。

C++17开始,若在类内声明时加上inline,就可以直接在类内初始化,而不必在类外再定义

1
2
3
4
class MyClass {
public:
inline static int counter = 0; // C++17新增写法
};

静态成员变量的性质

  1. 存储位置
  • 存放在静态存储区。
  1. 作用域
  • 作用域属于类作用域
  1. 生命周期
  • 与程序运行期一致。
  1. 初始化
  • 类内只是声明,不能直接分配存储空间(C++17之前)。
  • 必须在类外定义一次,否贼会链接错误。
  • 如果是const static整形或枚举,可以在类内直接初始化。

使用场景

  1. 统计类对象的数量
  2. 全局共享资源
  • 如数据库连接池、日志开关,只需要一份全局数据,但封装在类中更合理。
  1. 与静态成员函数配合
  • 静态成员函数不能访问普通成员变量,但可以访问静态成员变量。

四、静态成员函数——类中的静态成员函数

其也是类中所有对象所共有的。静态成员函数只能访问静态成员数据,其他静态成员函数和类外部的其他函数。

1
2
3
4
5
6
7
8
9
10
11
class MyClass {
public:
static int counter;
static void increaseCounter() { // 静态成员函数
counter++;
}
};

int MyClass::counter = 0;
// 可以通过类名和作用域解析运算符直接调用静态成员函数,不需要创建对象。
MyClass::increaseCounter();

静态成员函数的性质

  1. 不依赖对象存在
  2. 没有this指针
  • 在静态成员函数内部不能访问非静态成员变量,也不能调用非静态成员函数。
  1. 作用域属于类
  2. 生命周期
  • 整个程序运行期。

使用场景

  1. 操作静态成员变量
  2. 作为工具函数
  • 可以写一些与类相关,但不依赖对象的函数。
1
2
3
4
5
6
7
8
9
10
class MathUtil {
public:
static int add(int a, int b) {
return a + b;
}
};

int main() {
std::cout << MathUtil::add(3, 5) << std::endl; // 输出 8
}

参考

static在C++中的四种用法


c++中static的用法
https://delta0406.github.io/2025/09/11/技术/语言/CPP/c-中static的用法/
作者
执妄
发布于
2025年9月11日
许可协议