static
static
在 C++ 中的各种用法
以下是 static
的主要用法,包括静态变量、静态全局变量、静态局部变量、静态函数、静态成员函数和静态成员变量的详细说明。
#include <iostream>
#include <string>
// 1. 静态全局变量(文件作用域)
static int globalCount = 0; // 仅当前文件可见
// 2. 普通全局变量(对比)
int nonStaticGlobal = 0; // 其他文件可通过 extern 访问
// 3. 静态函数(文件作用域)
static void incrementGlobalCount() {
globalCount++;
std::cout << "Static globalCount: " << globalCount << "\n";
}
class MyClass
{
private:
// 4. 静态成员变量
static int staticMemberCount; // 共享于所有对象
int instanceCount;
public:
MyClass(int count) : instanceCount(count)
{
staticMemberCount++;
}
// 5. 静态成员函数
static int getStaticMemberCount()
{
return staticMemberCount; // 只能访问静态成员
}
int getInstanceCount() const {
return instanceCount;
}
// 6. 静态局部变量(示例)
void demonstrateStaticLocal()
{
static int localStaticVar = 0; // 仅初始化一次,保留值
localStaticVar++;
std::cout << "Static local variable: " << localStaticVar << "\n";
}
};
// 静态成员变量的定义(必须在类外定义)
int MyClass::staticMemberCount = 0;
int main()
{
// 测试静态全局变量
incrementGlobalCount(); // 输出 1
incrementGlobalCount(); // 输出 2
// 测试静态成员变量和静态成员函数
MyClass obj1(10);
MyClass obj2(20);
std::cout << "Static member count: " << MyClass::getStaticMemberCount() << "\n"; // 输出 2
std::cout << "Instance count obj1: " << obj1.getInstanceCount() << "\n"; // 输出 10
std::cout << "Instance count obj2: " << obj2.getInstanceCount() << "\n"; // 输出 20
// 测试静态局部变量
obj1.demonstrateStaticLocal(); // 输出 1
obj2.demonstrateStaticLocal(); // 输出 2
return 0;
}
1. 静态全局变量
- 定义:在文件作用域中声明的全局变量,前面加
static
。 - 作用:
- 限制变量的链接性为内部链接(internal linkage),仅在当前翻译单元(源文件)可见。
- 其他源文件无法通过
extern
访问。
- 特点:
- 初始化只发生一次,生命周期为整个程序运行期间。
- 默认初始化为 0(如果未显式初始化)。
- 示例:
1
static int globalCount = 0; // 仅当前文件可见
- 对比普通全局变量:
1
int nonStaticGlobal = 0; // 可被其他文件通过 extern 访问
- 对比普通全局变量:
2. 静态局部变量
- 定义:在函数或块作用域内声明的变量,前面加
static
。 - 作用:
- 变量只初始化一次,之后保留其值。
- 生命周期为整个程序运行期间,但作用域仅限于声明的块。
- 特点:
- 默认初始化为 0(如果未显式初始化)。
- C++11 及以后,静态局部变量的初始化是线程安全的
- 示例:
1
2
3
4
5void demonstrateStaticLocal() {
static int localStaticVar = 0; // 仅初始化一次
localStaticVar++;
std::cout << localStaticVar << "\n"; // 每次调用递增
}- 调用两次,输出
1
和2
。
- 调用两次,输出
3. 静态函数
- 定义:在文件作用域中声明的函数,前面加
static
。 - 作用:
- 限制函数的链接性为内部链接,仅在当前翻译单元可见。
- 防止其他源文件通过
extern
调用。
- 特点:
- 用于封装文件内部的辅助函数,类似于静态全局变量的限制。
- 示例:
1
2
3
4static void incrementGlobalCount() {
globalCount++;
std::cout << "Static globalCount: " << globalCount << "\n";
}
4. 静态成员变量
- 定义:在类中声明的成员变量,前面加
static
。 - 作用:
- 所有类对象共享同一份静态成员变量。
- 不属于某个具体对象,而是属于类本身。
- 特点:
- 必须在类外定义并初始化(通常在源文件中)。
- 生命周期为整个程序运行期间。
- 可通过类名直接访问(如
MyClass::staticMemberCount
)。
- 示例:
1
2
3
4
5class MyClass {
private:
static int staticMemberCount; // 声明
};
int MyClass::staticMemberCount = 0; // 定义并初始化
5. 静态成员函数
定义:在类中声明的成员函数,前面加
static
。作用:
- 不依赖于类的具体对象,只能访问类的静态成员(变量或函数),无法访问非静态成员函数和成员。
- 可通过类名直接调用(如
MyClass::getStaticMemberCount()
)。
特点:
- 没有隐式的
this
指针,因为不绑定到任何对象。 - 常用于访问或操作静态成员变量。
- 没有隐式的
示例:
1
2
3
4
5
6class MyClass {
public:
static int getStaticMemberCount() {
return staticMemberCount; // 访问静态成员
}
};
6. 注意事项与总结
- 生命周期与作用域:
- 所有
static
变量(全局、局部、成员)的生命周期都是程序运行期间。 - 作用域取决于声明位置(文件、函数、类)。
- 所有
- 线程安全:
- 静态局部变量在 C++11 及以后初始化是线程安全的。
- 静态全局变量和静态成员变量的访问需开发者自行确保线程安全。
- 内存管理:
- 静态变量存储在数据段(
.data
或.bss
),非堆或栈。 - 无需手动释放,程序结束时由系统自动回收。
- 静态变量存储在数据段(
- 与上下文的联系:
- 静态局部变量的线程安全特性在单例模式(如 Meyers’ Singleton)中非常有用
- 静态成员变量类似于饿汉式单例的预加载机制(程序启动时初始化)。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments