static是C/C++中让人迷惑的关键字。在一个文件对变量使用static关键字,则表示这个变量的作用范围仅限于本文件。
那么对于在头文件中使用static关键字,结果会如何呢。
首先,我们要明白,C++中对于头文件的处理。每个cpp文件在编译的时候都会将头文件(*.h)进行展开,这样就导致每个生成的*.o文件中均包含使用static修饰的变量,并且这个变量对其他文件不可见。结果是出现多份的变量,每个cpp文件中都只能访问本地的变量,这是一件较为危险的使用方法。
使用如下代码验证:
/* staticValue.hpp Check if static value will be copy in different .cpp s */ #pragma once static int a = 0;
/* funcA.cpp */ #include <iostream> #include "staticValue.hpp" int funcA() { std::cout<<"[funcA]"<<" &a\t= "<<&a<<std::endl; std::cout<<"[funcA]"<<" &::a\t= "<<&::a<<std::endl; return 0; }
/* funcB.cpp */ #include <iostream> #include "staticValue.hpp" int funcB() { std::cout<<"[funcB]"<<" &a\t= "<<&a<<std::endl; std::cout<<"[funcB]"<<" &::a\t= "<<&(::a)<<std::endl; return 0; }
/* main.cpp */ #include <iostream> #include "staticValue.hpp" extern int funcA(); extern int funcB(); int main(void) { std::cout<<"[main]"<<" &a:\t= "<<&a<<std::endl; std::cout<<"[main]"<<" &::a:\t= "<<&::a<<std::endl; funcA(); funcB(); return 0; }
编译执行
iceyer@iceyer:~/$ g++ -g -o static-value main.cpp funcA.cpp funcB.cpp iceyer@iceyer:~/$ ./static-value [main] &a: = 0x602198 [main] &::a: = 0x602198 [funcA] &a = 0x6021a0 [funcA] &::a = 0x6021a0 [funcB] &a = 0x6021a8 [funcB] &::a = 0x6021a8