C++存储类
前言
这一节我们将学习修饰符类型的的相关知识,可能会涉及到一些C++的基本语法以及C++变量类型、C++变量作用域的相关知识,如果你还有不明白的,请到C++基本语法和C++变量类型、C++变量作用域这里温故一下
C++存储类型
什么是存储类?
存储类决定了变量或函数的作用范围(在哪里可以访问)和生命周期(何时创建、何时销毁)。在C++中,存储类的关键字会放在变量或函数类型的前面,用来改变它们的默认行为。
C++中常见的存储类说明符
以下是C++存储类关键字的通俗解释:
1. auto(自动存储期,默认行为)
- 定义:这是C++的默认存储类说明符,通常可以省略不写。它表示变量的生命周期仅限于它所在的块(如函数内部)。
- 特点:
- 变量会在块结束时自动销毁。
- 在C++11后,
auto更多用于自动推导变量类型,而不是存储类。
- 示例:
1
2
3void function() {
auto int x = 10; // x 是局部变量,块结束后自动销毁
}
2. register(寄存器变量)
- 定义:建议编译器将变量存储在CPU寄存器中以提高访问速度。
- 特点:
- 在现代C++中(C++11及以后),
register已经被废弃,编译器会自动优化变量的存储。 - 示例:
1
2
3void function(register int x) {
// x 是建议存储在寄存器中的变量
}
- 在现代C++中(C++11及以后),
3. static(静态存储期)
- 定义:表示变量的生命周期贯穿整个程序的运行期。
- 特点:
- 函数内部的static变量:只初始化一次,函数多次调用时会保留上次的值。
- 全局变量或函数的static:限制变量或函数只能在当前文件中使用。
- 示例:
1
2
3
4
5void function() {
static int count = 0; // count 只初始化一次
count++;
std::cout << count; // 多次调用会保留上次的值
}
4. extern(外部链接)
- 定义:声明全局变量或函数,可以跨多个文件使用。
- 特点:
extern告诉编译器变量或函数是在别的文件中定义的。- 示例:
文件1:file1.cpp:文件2:1
int globalVar = 10; // 定义全局变量
file2.cpp:1
extern int globalVar; // 引用 file1.cpp 中的变量
5. mutable(可变成员变量)
- 定义:修饰类的成员变量,即使类对象是
const,也允许修改这个变量。 - 特点:
- 通常用于需要在
const成员函数中更新的变量,比如缓存或计数器。 - 示例:
1
2
3
4
5
6
7
8class Example {
public:
mutable int counter; // counter 可以在 const 函数中修改
void increment() const {
counter++; // 合法
}
};
- 通常用于需要在
6. thread_local(线程局部存储期,C++11 引入)
- 定义:表示每个线程都有变量的独立副本,变量的生命周期与线程一致。
- 特点:
- 适合多线程编程中需要每个线程独立数据的场景。
- 示例:
1
thread_local int threadVar = 0; // 每个线程都有自己的 threadVar
示例总结
以下代码展示了不同存储类的用法:
1 |
|
小总结
| 关键字 | 特点 |
|---|---|
auto |
默认存储类,生命周期随块结束,现代C++更多用于类型推导。 |
register |
提示编译器优化变量存储(C++11后废弃)。 |
static |
生命周期贯穿整个程序,但作用范围受限。 |
extern |
允许跨文件共享全局变量或函数。 |
mutable |
允许修改const对象的成员变量。 |
thread_local |
每个线程有独立变量副本,生命周期与线程一致(C++11后引入)。 |
常见存储类及其用途
1. auto(自动推导类型)
- 定义:自动根据初始化的值推断变量的类型。
- 特点:
- 省去了手动写类型的麻烦。
- 适合用在复杂类型的变量上,比如迭代器。
- 示例:
1
2
3auto a = 10; // 推断为 int
auto b = 3.14; // 推断为 double
auto c = "hello"; // 推断为 const char*
2. register(寄存器变量,C++11后已废弃)
- 定义:建议将变量存储在CPU寄存器中,以便快速访问。
- 特点:
- 提高访问速度,适合频繁使用的变量。
- 在现代编译器中,
register的效果已被优化算法替代。
- 示例:
1
register int i = 0; // 提示编译器将 i 存储在寄存器中
3. static(静态变量)
- 定义:变量的生命周期贯穿程序始终,无论它在局部还是全局作用域。
- 特点:
- 局部静态变量:函数内部的
static变量只初始化一次,值会在函数调用之间保留。 - 全局静态变量:只能在当前文件中使用,其他文件无法访问。
- 类静态变量:类中所有对象共享一个静态变量。
- 局部静态变量:函数内部的
- 示例:
1
2
3
4
5void counter() {
static int count = 0; // 只初始化一次
count++;
std::cout << count << std::endl;
}
4. extern(外部变量)
- 定义:声明一个全局变量或函数,使其在多个文件之间共享。
- 特点:
- 通常用于跨文件访问变量或函数。
- 示例:
文件1:file1.cpp文件2:1
int sharedVar = 42; // 定义全局变量
file2.cpp1
2extern int sharedVar; // 引用 file1 中的变量
std::cout << sharedVar;
5. mutable(可变成员变量)
- 定义:修饰类的成员变量,即使类对象是
const,这个变量也可以被修改。 - 特点:
- 通常用于缓存、计数器等需要在
const上下文中改变状态的场景。
- 通常用于缓存、计数器等需要在
- 示例:
1
2
3
4
5
6
7class Example {
mutable int counter; // 可变变量
public:
void increment() const {
counter++; // 合法
}
};
6. thread_local(线程本地存储,C++11引入)
- 定义:每个线程都有一个独立的变量副本,线程之间互不干扰。
- 特点:
- 适用于多线程编程。
- 每个线程的
thread_local变量在线程结束时销毁。
- 示例:
1
2
3
4
5thread_local int threadVar = 0;
void threadFunc(int id) {
threadVar = id; // 每个线程有独立的变量
}
使用场景总结
| 存储类 | 适用场景 |
|---|---|
auto |
自动推断变量类型,简化复杂类型的声明。 |
register |
提示频繁使用的变量(现代C++中已废弃)。 |
static |
保留局部变量值、限制全局变量访问范围、类成员共享变量。 |
extern |
跨文件共享全局变量和函数。 |
mutable |
在const对象中允许修改成员变量(如缓存或计数器)。 |
thread_local |
线程安全,每个线程都有独立的变量副本。 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Matou🚢!
评论








