C++学习笔记:static作用

本文最后更新于:2024年3月29日 上午

1. 静态变量

1.1 函数中的静态局部变量

当变量声明为static时,变量的空间将在程序的生命周期内分配。即使多次调用该函数,静态变量的空间也只分配一次,函数调用结束,变量不被销毁。这对于需要存储先前函数状态的程序非常有用。

1.2 静态全局变量

与static单词词意联系不大,容易忽略。

用static修饰的全局变量只能在本文件内访问,因此static具有限定访问范围的作用

当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//testq.cpp
#include "iostream"

using namespace std;

int a = 10;

void msg() {
cout << "Hello World" << endl;
}

//main.cpp
#include <iostream>

using namespace std;

int main(void) {
extern int a;
cout << a << endl;
extern void msg();
msg();
return 0;
}

程序运行结果如下:

由于test1.cpp中定义的全局变量a和函数msg没有被static修饰,具有全局可见性,所以在main.cpp中可以访问。如果使用static修饰:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//test1.cpp
#include "iostream"

using namespace std;

static int a = 10;

static void msg() {
cout << "Hello World" << endl;
}

//main.cpp
#include <iostream>

using namespace std;

int main(void) {
extern int a;
cout << a << endl;
extern void msg();
msg();
return 0;
}

运行程序,会报如下错误:

无法访问test1.cpp中定义的变量a和函数msg,因此报错。

1.3 类中的静态变量

声明为static的变量只被初始化一次。

由于它们在单独的静态存储中分配了空间,因此类中的静态变量由对象共享

对于不同的对象,不能有相同静态变量的多个副本。因为此,静态变量不能使用构造函数初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//test1.cpp
class Apple {
public:
static int count;
};

//main.cpp
#include <iostream>
#include "test1.cpp"

using namespace std;

int Apple::count = 0;

int main() {
Apple obj1;
Apple obj2;
obj1.count = 1;
obj2.count = 2;
cout << "obj1.count: "
<< obj1.count
<< endl
<< "obj2.count: "
<< obj2.count << endl;
}

上述main.cpp的输出为:

可以看到Apple类的静态变量count为多个对象共享,一个对象改变其值,所有对象的值都发生改变。

2. 静态成员

2.1 类对象为静态

与变量类似,类实例化的对象也有生命周期,考虑如下程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//test1.cpp
//
// Created by Gzl on 2022/8/11.
//
#include "iostream"

using namespace std;

class Apple {
public:
Apple() {
cout << "Inside Constructor" << endl;
}

~Apple() {
cout << "Inside Destructor" << endl;
}
};

//main.cpp
#include <iostream>
#include "test1.cpp"

using namespace std;

int main() {
int x = 0;
if (x == 0) {
Apple obj;
}
cout << "End of main" << endl;
}

程序运行结果如下:

在上面的程序中,对象在if代码块内声明,且为非静态对象,则该变量的生命周期仅在if代码块内。当进入if代码块时,创建对象并调用构造函数,并且在if代码块结束的时候调用析构函数销毁对象。

如果将对象声明为静态:

1
2
3
4
5
6
7
8
9
10
11
12
13
//main.cpp
#include <iostream>
#include "test1.cpp"

using namespace std;

int main() {
int x = 0;
if (x == 0) {
static Apple obj;
}
cout << "End of main" << endl;
}

结果如下所示:

由于static对象的声明周期为整个程序,因此在main函数结束时对象才会销毁。

2.2 类中的静态函数

与类中的静态数据成员和静态变量一样,静态成员函数也不依赖于类的对象。

可以使用对象和运算符“.”调用静态成员函数,但建议使用类名和范围解析运算符调用静态成员。

静态成员函数仅可以访问静态数据成员或其他静态成员函数,无法访问类的非静态成员。

本文为学习C++那些事 (github.com)所记笔记。


C++学习笔记:static作用
https://summersong.top/post/ed81569b.html
作者
SummerSong
发布于
2022年8月14日
更新于
2024年3月29日
许可协议