这一篇就借着介绍 C++ 类内静态成员变量和静态成员函数的机会,彻底介绍一下 C++ 中的static
如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢
C/C++ 共有的用途
静态局部变量
- 静态局部变量即在局部变量前面加 static 修饰
- 只执行一次初始化,延长了局部变量的生命周期,在程序结束的时候才释放
void func() {
static int n; // 静态局部变量
cout << n++ << endl;
cout << &n << endl;
}
// 1. 第一次调用时全局变量默认初始化为0,后面调用不再进行初始化
// 2. 在程序中多次调用该函数输出的地址是一样的,是同一变量(证明不是很严谨,局部变量也会出现这种情况)
总结
- 静态局部变量在全局/静态区分配内存空间
- 静态局部变量在程序执行到该对象的声明处时被首次初始化,之后的函数调用不再进行初始化
- 静态局部变量一般在声明处初始化,若没有显式初始化,会被OS自动初始化为0
- 它始终驻留在全局/静态区,直到程序运行结束,但其作用域为局部作用域,也就是不能在函数体外面使用它
静态全局变量
- 静态全局变量只能在当前的文件中访问,其它文件不可访问,即使是extern也不行
// ====== 测试一 ======
// file: a.cpp
#include <iostream>
using namespace std;
int n; // 全局变量
void func();
int main() {
cout << n++ << endl;
func();
system("pause");
return 0;
}
// file: b.cpp
#include <iostream>
using namespace std;
extern int n;
void func() {
cout << n << endl;
}
// 可正常运行,运行结果:0 1
// ====== 测试二 ======
// file: a.cpp
#include <iostream>
using namespace std;
static int n; // 静态全局变量
void func();
int main() {
cout << n << endl;
func();
system("pause");
return 0;
}
// file: b.cpp
#include <iostream>
using namespace std;
extern int n;
void func() {
cout << n << endl;
}
// 报错
总结
- 静态全局变量不能被其它文件所用(全局变量可以)
- 其它文件中可以定义相同名字的变量,不会发生冲突
静态函数(非成员函数)
- 只能在当前文件中访问,不可在其它文件中调用(可见静态函数和静态全局变量类似)
// ====== 测试一 ======
// file: a.cpp
#include <iostream>
using namespace std;
int n; // 全局变量
void func();
int main() {
cout << n++ << endl;
func();
system("pause");
return 0;
}
// file: b.cpp
#include <iostream>
using namespace std;
extern int n;
void func() { // 普通全局函数
cout << n << endl;
}
// 可正常运行,运行结果:0 1
// ====== 测试二 ======
// file: a.cpp
#include <iostream>
using namespace std;
int n; // 全局变量
extern void func();
int main() {
cout << n << endl;
func();
system("pause");
return 0;
}
// file: b.cpp
#include <iostream>
using namespace std;
extern int n;
static void func() { // 静态全局函数
cout << n << endl;
}
// 报错
总结
- 静态函数不能被其它文件所用
- 其它文件中可以定义相同名字的函数,不会发生冲突
C++ 特有的用途
静态成员变量
- 类的所有实体对象共享这个变量
class Test {
public:
double d;
static int n;
};
int Test::n; // 静态成员变量需要在类外声明(分配空间,可以显式初始化,默认初始化为0)
cout << sizeof(Test) << endl;
cout << Test::n << endl;
// 运行结果:8 0
总结
- 静态成员变量存储在全局/静态区,静态成员变量只有在类外声明时才分配空间,可显式初始化,不显式初始化OS默认初始化为0
- 静态成员变量属于类不属于对象,sizeof()的结果不包括静态成员变量大小
- 可通过对象调用,也可以通过类名作用域调用(非静态成员变量只能通过对象调用)
静态成员函数
- 静态成员函数中只能调用静态成员变量和静态成员函数
class Test {
public:
static void show() {
cout << n << endl;
}
private:
double d;
static int n;
};
int Test::n;
cout << sizeof(Test) << endl;
Test::show();
// 运行结果:8 0
总结
- 静态成员之间可以相互访问,包括静态成员函数访问静态成员变量和访问静态成员函数
- 非静态成员函数可以任意地访问静态成员函数和静态成员变量
- 静态成员函数不能访问非静态成员函数和非静态成员变量
- 调用静态成员函数,可通过对象调用,也可以通过类名作用域调用(非静态成员变量只能通过对象调用)
参考文章:
[1] c++中static的用法详解
如果未特殊说明,以上测试均是在win10 vs2017 64bit编译器下进行的