static关键字java中也有, 是静态的意思, 在java中可以用来修饰变量和方法. 修饰变量时, 变量就成为类变量, 对于所有对象都具有相同的值; 修饰方法时, 方法就成为类方法, 不能访问成员变量.
c++中的关键字也类似, 用来修饰变量和方法, 不过比java中还稍微多一些功能:
(1) 修饰全局变量: 全局变量将仅在该文件内可用, 其它文件中无法访问到这个变量
(2) 修饰全局方法: 全局方法将仅在该文件内可用, 其它文件中将无法访问到这个方法
(3) 修饰局部变量: 可以将其看作static修饰的全局变量了, 只是作用范围变为局部, 和局部变量原来的作用范围相同.
(4) 修饰类变量: 和java中类似, 成为类变量, 对于所有对象都具有相同的值
(5) 修饰类方法: 和java中类似, 成员类方法, 不能访问成员变量.
(1)static修饰全局变量
Static.cpp
static int s_int = 10;
测试1, 通过声明extern int s_int; 看能不能访问到s_int
Main.cpp
#includeusing namespace std; extern int s_int; int main(void) { cout << "s_int:" << s_int << '\n'; }
编译代码, 编译器将提示错误: undefined reference to `s_int', 说明Main.cpp文件无法访问到Static.cpp中的s_int
测试2, 可以在多个文件中定义s_int变量, 且不会出现重定义的错误, 同时不同文件中定义的s_int变量都相互独立, 互不干扰.
Static2.cpp
static int s_int = 11;
Main.cpp
#include#include "Static.cpp" // include的效果就相当于把代码copy到Main.cpp的这里, 也就是相当于在Main.cpp的这里定义了s_int, 所以main中可以访问到s_int. using namespace std; int main(void) { cout << "s_int:" << s_int << '\n'; return 0; }
#include "Static.cpp"时, 得到的结果是10; #include "Static2.cpp"时, 得到的结果将是11. 所以这个程序中其实是有两个相互独立的s_int存在.
(2) static修饰全局方法
Static.h
#ifndef STATIC_H_ #define STATIC_H_ static void staticMethod(); #endif
Static.cpp
#includeusing namespace std; static void staticMethod() { cout << "staticMethod()" << '\n'; }
Main.cpp
#include#include "Static.h" using namespace std; int main(void) { staticMethod(); return 0; }
编译后编译器会提示错误, 'void staticMethod()' used but never defined, 使用了staticMethod(), 但并没有定义他.
额, 不是在Static.cpp中定义了么?
和之前static修饰变量一样, static修饰全局方法后, Static.h和Static.cpp中的两个staticMethod()就变成了完全没有任何关系的两个独立的方法了, 那当然Static.h中的那个方法仅仅是声明了, 并没有定义.
解决办法, 那就是为Static.h中的那个staticMethod进行定义.
Static.h
#ifndef STATIC_H_ #define STATIC_H_ #includestatic void staticMethod(); static void staticMethod() { std::cout << "Static.h : staticMehtod()" << '\n'; } #endif
(3) static修饰局部变量
其实就可以看作是static全局变量, 仅仅是作用范围变小, 仅在定义他的代码块中可以访问到.
同时他和局部变量也有一些区别, 局部变量在每次进入方法时初始化, 方法结束时回收掉, 而static局部变量是仅在第一调用方法时初始化, 接下来的调用将不再初始化, 且在方法结束时不会被回收掉.
Main.cpp
#includevoid localStatic() { static int s_int = 10; std::cout << "s_int:" << s_int << '\n'; s_int++; } int main(void) { for (int i = 0; i < 10; i++) { localStatic(); } }
(3) 修饰类变量时
Static.h
#ifndef STATIC_H_ #define STATIC_H_ class Static { public: static int s_int; } #endif
Static.cpp
#include "Static.h" int Static::s_int = 10;
Main.cpp
#include "Static.h" #includeint main(void) { Static s1; Static s2; std:: cout << "s1.s_int:" << s1.s_int << '\n'; std:: cout << "s2.s_int:" << s2.s_int << '\n'; // 修改后, 两个对象还是具有相同的值 s1.s_int = 11; std:: cout << "s1.s_int:" << s1.s_int << '\n'; std:: cout << "s2.s_int:" << s2.s_int << '\n'; }
(3) 修饰类方法时
Static.h
#ifndef STATIC_H_ #define STATIC_H_ class Static { public: int m_int; static int s_int; Static(); static void staticMethod(); } #endif
Static.cpp
#include "Static.h" Static::Static() { m_int = 1; s_int = 2; } void Static::staticMethod() { // m_int = 3; // 无法访问成员变量 s_int = 4; // 类变量可以访问 }
Main.cpp
#include#include "Static.h" int main(void) { Static s; std::cout << "Static.m_int:" << s.m_int << '\n'; // 静态方法的调用和java中也类似, 既可以在对象上调用, 也可以使用类直接调用, 但推荐第二种. s.staticMethod(); Static::staticMethod(); }