← 目录 / 第十二章 · 类与面向对象 / 12.7 静态成员 static

12.7 静态成员 static

普通成员变量每个对象都有一份,而静态成员变量所有对象共享同一份——它不属于任何一个对象,而是属于整个类。

本页目录
12.7.1 用班级公告栏理解 static

班里每个同学都有自己的笔记本——这是普通成员变量,每人一份,互不干扰。

但班级的公告栏只有一块,全班共用,任何一个人写上去,所有人都能看到——这就是静态成员变量。它属于整个班级(类),而不属于某一个同学(对象)。

对象 s1 name = "Alice" score = 95 count → 共享 对象 s2 name = "Bob" score = 82 count → 共享 对象 s3 name = "Carol" score = 77 count → 共享 static int count 3 每个对象各有独立的 name 和 score count 只有一份,所有对象共用,记录创建了多少个对象
普通成员变量(namescore)每个对象各有一份,存在对象自己的内存里。
静态成员变量(count)只有一份,存在类的公共区域,所有对象读写的都是同一个值。
12.7.2 静态成员变量

在成员变量前加 static 关键字即可。但有一个特别的规定:静态成员变量必须在类外单独定义(初始化),不能只在类内声明就了事。

C++ · 静态成员变量:用来统计对象数量
1class Student {
2public:
3 string name;
4 static int count; // 类内声明,注意只是声明
5
6 Student(string n) : name(n) {
7 count++; // 每创建一个对象就 +1
8 }
9 ~Student() { count--; } // 每销毁一个对象就 -1
10};
11
12int Student::count = 0; // ← 类外定义并初始化,不能省略!
13
14int main() {
15 Student s1("Alice");
16 Student s2("Bob");
17 cout << Student::count; // 输出:2(用 类名:: 访问)
18 cout << s1.count; // 也可以用对象访问,但不推荐(容易误以为是独立的)
19}
⚠️
类外定义不能忘:静态成员变量在类内只是声明,告诉编译器"有这个东西"。真正分配内存、指定初始值,必须在类外写 int Student::count = 0;。忘了写,链接时会报"未定义的引用"错误。
12.7.3 静态成员函数

成员函数也可以用 static 修饰。静态成员函数和静态变量一样,不依赖任何具体的对象,可以直接通过类名调用,无需创建对象。

正因为如此,静态成员函数里没有 this 指针——它不知道也不关心是哪个对象在调用它,因此它只能访问静态成员,不能访问普通成员变量。

C++ · 静态成员函数
1class Student {
2private:
3 string name;
4 static int count;
5public:
6 Student(string n) : name(n) { count++; }
7 ~Student() { count--; }
8
9 static int GetCount() { // 静态成员函数
10 return count; // ✅ 可以访问静态成员
11 // return name; ❌ 不能访问普通成员(没有 this)
12 }
13};
14int Student::count = 0;
15
16int main() {
17 cout << Student::GetCount(); // 输出:0(不需要创建对象就能调用)
18 Student s1("Alice"), s2("Bob");
19 cout << Student::GetCount(); // 输出:2
20}
💡
什么时候用静态成员函数?当这个函数的逻辑与具体对象无关,只和整个类有关时,就适合用 static。最典型的例子:获取对象计数、工厂方法(创建对象的辅助函数)、工具类里的纯计算函数。
12.7.4 静态 vs 普通成员对比
对比项普通成员静态成员
属于谁 每个对象各有一份 整个类共享一份
内存位置 对象内部(栈或堆) 程序的静态存储区
生命周期 随对象创建/销毁 程序启动到结束,始终存在
访问方式 对象.成员 类名::成员(推荐)或 对象.成员
能否访问 this ✅ 有 this 指针 ❌ 没有 this 指针
初始化位置 构造函数 / 初始化列表 类外单独定义(必须)
12.7.5 实用场景

静态成员在以下几个场景非常好用:

C++ · 场景一:全局配置常量
1class Game {
2public:
3 static const int MAX_PLAYERS = 4; // const static 可以直接在类内初始化
4 static const int MAP_SIZE = 100;
5};
6
7// 用类名直接访问,清晰地表达"这是 Game 的配置"
8int arr[Game::MAP_SIZE];
C++ · 场景二:单例模式(全局唯一实例)
1class Config {
2private:
3 Config() {} // 构造函数私有,外部无法直接创建
4 static Config* instance;
5public:
6 static Config* GetInstance() {
7 if (!instance)
8 instance = new Config(); // 第一次调用才创建
9 return instance; // 之后返回同一个实例
10 }
11};
12Config* Config::instance = nullptr;
📖
本节小结
static 成员变量:整个类共享一份,生命周期贯穿程序始终,必须在类外定义。
static 成员函数:无 this 指针,只能访问静态成员,用 类名:: 直接调用。
・常见用途:对象计数器、全局配置常量、单例模式。