C++中static用法总结
1用于局部变量
C++中局部变量有三种:
(1)auto:此关键词常常省略。auto type a 常常简写为type a。
如:
int a=auto int a
存储在内存的栈中,只在此局部区域有定义,程序执行过此局部区域自动释放。
(2)static:有以下特点:
(1)声明在局部区域,第一次执行时定义,以后就不再定义;
(2)同auto和register,只在其定义的局部区域有定义;
(3)区别与auto和register,static局部变量存储在内存的静态变量区。所以下次执行到此局部区域时,上次的结果值得以保留。
例:
int get() { static int a=0; return a++; } int main() { cout<<get()<<get(); return 0; }
程序输出:01。第二次不再执行static变量a的定义。
(3)register:基本同auto,只是直接存储在CPU的寄存器组。
2用于全局变量和全局函数
你可能会问?用在局部就存储在内存的静态变量区了,那么定义到全局又有什么作用呢?
这种定义常用于有多个文档的工程的变量/函数保护。举个栗子:
static int a, static void fun();
上面定义了一个全局static变量a,一个static函数fun。
加上static可以保证其它文档不可以访问到他们。回想一下,怎样让一个变量在多个文档中都可以使用?extern!对的。
Talk is cheap, I will show you the code:
/*FileName: File1.cpp */ int a; /*FileName: File2.cpp*/ extern int a;
在File1.cpp中定义了int a,只需在File2.cpp中extern一下,便可以把File1.cpp中的变量a直接拿来用,他们是同一个变量。
那么,如果File1.cpp中,我们把a的定义换为static int a,那么在File2.cpp中extern int a会发生什么呢?肯定报错啦,我刚刚都说过了,static定义在全局,可以起到保护作用,保证此定义只能被本文档使用。
函数的情况也是一样的。
3用于成员变量
class A { public: static int a; };
a便成为了A的静态成员变量。
(1)它只属于A,不属于A的任何一个对象。
(2)它不能被A的构造函数初始化,需要单独定义、初始化,其方法和类成员函数的定义相同。
(3)两种访问方法:
1)通过类A::a; 2)通过类对象/指针:obj_A.a,ptr_A->a。
例子:
class A { public: static int a; }; int A::a = 100 ;
int _tmain(int argc, _TCHAR* argv[]) { A obj_A; A *ptr_A=&obj_A; cout << A::a << " " << obj_A.a << " " << ptr_A->a << endl; while (1); return 0; }
4用于成员函数
成员函数有了static的修饰便成了静态成员函数,它的基本属性与静态成员变量一致。另外,由于虚函数要在对象中创建虚表,所以虚函数无法为static函数。
小总结:不能为虚的几种函数:普通函数、友元函数、构造函数、静态成员函数、内联函数。
静态成员函数最大的特点是它没有this指针,它的其它特性都因此而来。如果对一个静态成员函数求指针,得到的将不是一个指向member function函数的指针,而是指向普通function的指针。例如
有classA一个函数static void fun();&classA::fun()会得到void(*)(),而不是void(classA::*)()。也就是说,static最大程序上近似于非成员函数。这种特性提供了一个意想不到的好处:static成员函数可以作为callback函数!
C++把静态成员函数称作类方法,把其他成员函数称作实例方法。不同之处:
(1)类方法只有一份实例,不属于任何一个对象。
(2)类方法只能调用类方法,不能调用实例方法。而实例方法可以调用类方法。
(3)类方法不能调用非静态成员变量
最后一个栗子:
class cA { public: int objVar1; static int classVar1; static void classFun1() { classVar1 = 0; objVar1 = 0;//错误!!!类方法无法访问非静态成员函数 classFun2(); objFun1();//错误!!!类方法无法调用实例方法 }; static void classFun2(){}; void objFun1() { classVar1 = 0; objVar1 = 0; classFun1(); objFun2(); }; void objFun2(){}; };