C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。
?
?
?
一、面向过程设计中的static
?
1、静态全局变量
?
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:
?
//Example 1 #include <iostream.h> void fn(); static int n; //定义静态全局变量 void main() { n=20; cout<<n<<endl; fn(); } void fn() { n++; cout<<n<<endl; }
?
? ?静态全局变量有以下特点:
对于一个完整的程序,在内存中的分布情况如下图:
?
?
一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。
?
细心的读者可能会发现,将Example 1中的代码
?
static int n; //定义静态全局变量
??改为
?
int n; //定义全局变量?
程序照样正常运行。的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
你可以将上述示例代码改为如下:
?
//Example 2 //File1 #include <iostream.h> void fn(); static int n; //定义静态全局变量 void main() { n=20; cout<<n<<endl; fn(); } //File2 #include <iostream.h> extern int n; void fn() { n++; cout<<n<<endl; }
? ? 编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。试着将:
?
static int n; //定义静态全局变量
?
? ? 改为
?
int n; //定义全局变量
?
? ? 再次编译运行程序,细心体会全局变量和静态全局变量的区别。
?
? ? 注意事项:
?
?
2、静态局部变量
?
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。
?
我们先举一个静态局部变量的例子,如下:
//Example 3 #include <iostream.h> void fn(); void main() { fn(); fn(); fn(); } void fn() { static n=10; cout<<n<<endl; n++; }
//Example 4 #include <iostream.h> static void fn();//声明静态函数 void main() { fn(); } void fn()//定义静态函数 { int n=10; cout<<n<<endl; }? ? ? 定义静态函数的好处:
//file1.cpp static int varA; int varB; extern void funA() { ... } static void funB() { ... } //file2.cpp extern int varB; // 使用file1.cpp中定义的全局变量 extern int varA; // 错误! varA是static类型, 无法在其他文件中使用 extern vod funA(); // 使用file1.cpp中定义的函数 extern void funB(); // 错误! 无法使用file1.cpp文件中static函数?
//Example 5 #include <iostream.h> class Myclass { public: Myclass(int a,int b,int c); void GetSum(); private: int a,b,c; static int Sum;//声明静态数据成员 }; int Myclass::Sum=0;//定义并初始化静态数据成员 Myclass::Myclass(int a,int b,int c) { this->a=a; this->b=b; this->c=c; Sum+=a+b+c; } void Myclass::GetSum() { cout<<"Sum="<<Sum<<endl; } void main() { Myclass M(1,2,3); M.GetSum(); Myclass N(4,5,6); N.GetSum(); M.GetSum(); }? ? ? 可以看出,静态数据成员有以下特点:
//Example 6 #include <iostream.h> class Myclass { public: Myclass(int a,int b,int c); static void GetSum();/声明静态成员函数 private: int a,b,c; static int Sum;//声明静态数据成员 }; int Myclass::Sum=0;//定义并初始化静态数据成员 Myclass::Myclass(int a,int b,int c) { this->a=a; this->b=b; this->c=c; Sum+=a+b+c; //非静态成员函数可以访问静态数据成员 } void Myclass::GetSum() //静态成员函数的实现 { // cout<<a<<endl; //错误代码,a是非静态数据成员 cout<<"Sum="<<Sum<<endl; } void main() { Myclass M(1,2,3); M.GetSum(); Myclass N(4,5,6); N.GetSum(); Myclass::GetSum(); }? ? ? 关于静态成员函数,可以总结为以下几点: