文章目录
- 0. 语法
- 1. 自动存储类
- 自动存储类对象的属性
- 自动存储类的例子
- 2. 外部存储类
- extern存储类对象的属性
- extern存储类的例子
- 3. 静态存储类
- 静态存储类的属性
- 静态存储类的例子
- 4. 寄存器存储类
- 寄存器存储类对象的属性
- 寄存器存储类例子
- 5. 可变(mutable)存储类
- 可变存储类的属性
- 可变存储类的例子
- 6. thread_local存储类
- thread_local存储类属性
- thread_local存储类的例子
C++存储类用于描述变量/函数的特性。它确定了生命周期、可见性、默认值和存储位置,这有助于我们在程序运行时跟踪特定变量。存储类说明符用于指定变量的存储类。
0. 语法
要指定变量的存储类,请遵循以下语法:
storage_class var_data_type var_name;
C++使用了6个存储类,如下所示:
- auto Storage Class
- register Storage Class
- extern Storage Class
- static Storage Class
- mutable Storage Class
- thread_local Storage Class
以下是对每个存储类的详细说明:
1. 自动存储类
自动存储类是块内声明的所有变量的默认类。auto 代表自动,块中声明的所有局部变量都自动属于此类。
自动存储类对象的属性
- 范围:本地/局部
- 默认值:垃圾值
- 内存位置:RAM
- 生命期:直到其范围结束
自动存储类的例子
// C++ Program to illustrate the auto storage class
// variables
#include <iostream>
using namespace std;
void autoStorageClass()
{
cout << "Demonstrating auto class\n";
// Declaring an auto variable
int a = 32;
float b = 3.2;
char* c = "GeeksforGeeks";
char d = 'G';
// printing the auto variables
cout << a << " \n";
cout << b << " \n";
cout << c << " \n";
cout << d << " \n";
}
int main()
{
// To demonstrate auto Storage Class
autoStorageClass();
return 0;
}
输出
Demonstrating auto class
32
3.2
GeeksforGeeks
G
注意:在C++早期,我们可以使用auto关键字显式声明自动变量,但在C++11之后,auto关键字的含义发生了变化,我们不能再使用它来定义自动变量。
2. 外部存储类
extern存储类只是简单地告诉我们变量是在其他地方定义的,而不是在使用它的同一块中(即外部链接)。基本上,该值在不同的块中被赋值,也可以在不同的块中重写/更改。外部变量只不过是一个全局变量,该全局变量在声明时使用合法值初始化,以便在其他地方使用。
在任何函数/块中的声明/定义之前放置 “extern” 关键字,可以将普通全局变量设置为 extern。使用外部变量的主要目的是,可以在大型程序的两个不同文件之间访问它们。
extern存储类对象的属性
- 范围:全局
- 默认值:0
-
- 内存位置:RAM
- 生命期:直到程序结束
extern存储类的例子
// C++ Program to illustrate the extern storage class
#include <iostream>
using namespace std;
// declaring the variable which is to
// be made extern an initial value can
// also be initialized to x
int x;
void externStorageClass()
{
cout << "Demonstrating extern class\n";
// telling the compiler that the variable
// x is an extern variable and has been
// defined elsewhere (above the main
// function)
extern int x;
// printing the extern variables 'x'
cout << "Value of the variable 'x'"
<< "declared, as extern: " << x << "\n";
// value of extern variable x modified
x = 2;
// printing the modified values of
// extern variables 'x'
cout << "Modified value of the variable 'x'"
<< " declared as extern: \n"
<< x;
}
int main()
{
// To demonstrate extern Storage Class
externStorageClass();
return 0;
}
输出
Demonstrating extern class
Value of the variable 'x'declared, as extern: 0
Modified value of the variable 'x' declared as extern:
2
有关外部变量如何工作的更多信息,请查看此链接。
3. 静态存储类
静态存储类用于声明在C++语言中编写程序时常用的静态变量。静态变量具有即使在超出其作用域后也能保留其值的特性!因此,静态变量保存了它们在作用域中最后一次使用的值。
我们可以说,它们只初始化一次,并且一直存在到程序终止。因此,没有分配新的内存,因为它们没有被重新声明。全局静态变量可以在程序中的任何位置访问。
静态存储类的属性
- 范围:本地/局部
- 默认值:0
-
- 内存位置:RAM
- 生命期:直到程序结束
注意:全局静态变量可以在任何函数中访问。
静态存储类的例子
// C++ program to illustrate the static storage class
// objects
#include <iostream>
using namespace std;
// Function containing static variables
// memory is retained during execution
int staticFun()
{
cout << "For static variables: ";
static int count = 0;
count++;
return count;
}
// Function containing non-static variables
// memory is destroyed
int nonStaticFun()
{
cout << "For Non-Static variables: ";
int count = 0;
count++;
return count;
}
int main()
{
// Calling the static parts
cout << staticFun() << "\n";
cout << staticFun() << "\n";
// Calling the non-static parts
cout << nonStaticFun() << "\n";
cout << nonStaticFun() << "\n";
return 0;
}
输出
For static variables: 1
For static variables: 2
For Non-Static variables: 1
For Non-Static variables: 1
4. 寄存器存储类
寄存器存储类使用“register”关键字声明寄存器变量,该关键字具有与自动变量相同的功能。唯一的区别是,如果有可用的寄存器,编译器会尝试将这些变量存储在微处理器的寄存器中。这使得程序运行时,寄存器变量的使用比存储在内存中的变量的使用快得多。如果没有可用寄存器,则这些寄存器变量仅存储在内存中。
这里需要注意的一个重要而有趣的点是,我们不能使用指针来获得寄存器变量的地址。
寄存器存储类对象的属性
- 范围:本地/局部
- 默认值:垃圾值
-
- 内存位置:CPU中的寄存器或RAM
- 生命期:直到其范围结束
寄存器存储类例子
// C++ Program to illustrate the use of register variables
#include <iostream>
using namespace std;
void registerStorageClass()
{
cout << "Demonstrating register class\n";
// declaring a register variable
register char b = 'G';
// printing the register variable 'b'
cout << "Value of the variable 'b'"
<< " declared as register: " << b;
}
int main()
{
// To demonstrate register Storage Class
registerStorageClass();
return 0;
}
输出
Demonstrating register class
Value of the variable 'b' declared as register: G
注意:register关键字在C++17以后的版本中已被弃用。
5. 可变(mutable)存储类
有时需要通过const函数修改类/结构体的一个或多个数据成员,即使您不希望该函数更新类/结构体中的其他成员。使用mutable关键字可以很容易地执行此任务。关键字mutable主要用于允许修改const对象的特定数据成员。
当我们将函数声明为const时,传递给函数的指针就变成了const。给变量添加mutable可以让const指针改变成员。
可变存储类的属性
可变说明符不影响对象的链接或生存期。它将与在该位置声明的正常对象相同。
可变存储类的例子
// C++ program to illustrate the use of mutalbe storage
// class specifiers
#include <iostream>
using std::cout;
class Test {
public:
int x;
// defining mutable variable y
// now this can be modified
mutable int y;
Test()
{
x = 4;
y = 10;
}
};
int main()
{
// t1 is set to constant
const Test t1;
// trying to change the value
t1.y = 20;
cout << t1.y;
// Uncommenting below lines
// will throw error
// t1.x = 8;
// cout << t1.x;
return 0;
}
输出
20
6. thread_local存储类
thread_local存储类是在C++11中添加的新存储类。我们可以使用thread_local存储类说明符将对象定义为thread_local。thread_local变量可以与其他存储说明符(如static或extern)组合,thread_local对象的属性也会相应更改。
thread_local存储类属性
- 内存位置:RAM
- 生命期:直到它的线程结束
thread_local存储类的例子
// C++ program to illustrate the use of thread_local storage
// sprecifier
#include <iostream>
#include <thread>
using namespace std;
// defining thread local variable
thread_local int var = 10;
// driver code
int main()
{
// thread 1
thread th1([]() {
cout << "Thread 1 var Value: " << (var += 18) << '\n';
});
// thread 2
thread th2([]() {
cout << "Thread 2 var Value: " << (var += 7) << '\n';
});
// thread 3
thread th3([]() {
cout << "Thread 3 var Value: " << (var += 13) << '\n';
});
th1.join();
th2.join();
th3.join();
return 0;
}
输出
Thread 1 var Value: 28
Thread 2 var Value: 17
Thread 3 var Value: 23
可以看到,每个线程都有自己的thread_local变量副本,并且只被分配了在其可调用文件中指定的值。