在C++中,static关键字根据出现位置的不同,具有完全不同的语义。它既可以修饰局部变量、全局变量,也能修饰类的成员变量和成员函数。下面分别说明这三种主要用法。

一、static局部变量
当static修饰函数内的局部变量时,该变量只会在第一次进入函数时初始化,之后调用函数不再重新初始化,且生命周期一直持续到程序结束,但作用域仍限于函数内部。
#include <iostream>
void count() {
static int num = 0; // 只初始化一次
num++;
std::cout << "调用次数: " << num << std::endl;
}
int main() {
count(); // 输出 1
count(); // 输出 2
count(); // 输出 3
return 0;
}
上面的例子中,num被声明为static局部变量,每次调用count()都在原有基础上递增,不会因函数退出而销毁。
二、static全局变量
在函数外定义的全局变量,若加上static,则链接属性变为内部链接,仅在定义它的源文件内可见,其他文件即使使用extern声明也无法访问,可有效避免多文件命名冲突。
// file1.cpp static int g_value = 10; // 仅file1.cpp可见 // file2.cpp // extern int g_value; // 错误,无法访问file1中的static全局变量
如果不加static,全局变量默认具有外部链接,多个文件包含同一头文件定义时容易引发重复定义错误。
三、static类成员
static修饰类的成员变量或成员函数时,它们属于类本身,而不是某个对象。所有类对象共享同一份static成员变量,可通过类名直接访问,无需创建实例。
#include <iostream>
class Counter {
public:
static int total; // 声明static成员变量
Counter() { total++; }
static void showTotal() { // static成员函数
std::cout << "对象总数: " << total << std::endl;
}
};
int Counter::total = 0; // 类外定义并初始化
int main() {
Counter a, b, c;
Counter::showTotal(); // 输出 对象总数: 3
return 0;
}
需要注意,static成员函数没有this指针,不能访问非static成员,只能操作static成员或调用其他static函数。
用法对比
| 修饰对象 | 主要作用 | 生命周期 |
|---|---|---|
| 局部变量 | 保持值持久,只初始化一次 | 程序运行期 |
| 全局变量 | 限制文件内可见,避免冲突 | 程序运行期 |
| 类成员 | 类级别共享数据或方法 | 程序运行期 |
小结
掌握static在局部变量、全局变量和类成员上的不同用法,是写好C++模块和面向对象代码的基础。实际开发中应根据需要控制变量可见性与共享范围,减少耦合和错误。