存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。
注意:从 C++ 17 开始,auto 关键字不再是 C++ 存储类说明符,且 register 关键字被弃用。
auto存储类
作用:1.声明变量时根据初始化表达式自动推断该变量的类型。2.声明函数时函数返回值的占位符
register存储类
作用:register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小
例:register int miles;
注意:1.不能对它应用一元的 '&' 运算符(因为它没有内存位置)。2.定义 'register' 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。
static存储类
作用:1.static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。2.static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。
extern存储类
作用:1.extern 存储类用于提供一个全局变量的引用。常用于当有两个或多个文件共享相同的全局变量或函数的时候
mutable存储类
注意:1.mutable 说明符仅适用于类的对象。2.mutable不能修饰const 和 static 类型的变量。
作用:mutable 修饰的成员变量可以通过 const 成员函数修改。
场景:被const关键字修饰的函数的一个重要作用就是能够保护类中的成员变量不被修改。但是,在某些特殊情况下,我们可能需要在const函数中修改类的某些成员变量,但是我们又不能去掉const,因为我们只想修改某个成员变量,其余成员变量仍然希望被const保护。
例:我要测试一个方法的被调用次数。
class Person {
public:
Person();
~Person();
int getAge() const; /*调用方法*/
int getCallingTimes() const; /*获取上面的getAge()方法被调用了多少次*/
private:
int age;
char *name;
float score;
int m_nums; /*用于统计次数*/
};
问题:getAge()方法是const方法,无法修改m_nums这个变量
解决:使用mutable关键字
class Person {
public:
Person();
~Person();
int getAge() const; /*调用方法*/
int getCallingTimes() const; /*获取上面的getAge()方法被调用了多少次*/
private:
int age;
char *name;
float score;
mutable int m_nums; /*用于统计次数*/
};
这样子就可以在getAge()中修改m_nums了
thread_local 存储类
使用 thread_local 说明符声明的变量仅可在它在其上创建的线程上访问。变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。
thread_local 说明符可以与 static 或 extern 合并。
thread_local 仅应用于数据声明和定义,不能用于函数声明或定义。