本文共 4430 字,大约阅读时间需要 14 分钟。
原文:
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。
静态全局变量
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:
#includeusing namespace std;void fn();static int n; //定义静态全局变量void main() { n=20; cout< <
静态全局变量有以下特点:
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分为代码区、全局数据区、堆区、栈区。
一般程序中由new产生的动态数据存放在堆区,函数内部的局部变量存放在栈区。局部变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。上面的代码中将static int n; //定义静态全局变量
改为int n; //定义全局变量
。程序照样正常运行。的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
您可以将上述示例代码改为如下:
//File1#includeusing namespace std;void fn();static int n; //定义静态全局变量void main() { n=20; cout< < using namespace std;extern int n;void fn() { n++; cout< <
编译并运行,发现上述代码可以分别通过编译,但运行时出现错误。试着将static int n; //定义静态全局变量
改为int n; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。
静态局部变量
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。 我们先举一个静态局部变量的例子,如下:
#includeusing namespace std;void fn();void main() { fn(); fn(); fn();}void fn() { static n=10; cout< <
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
静态局部变量有以下特点:
静态函数
在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。
#includeusing namespace std;static void fn(); //声明静态函数void main() { fn();}void fn() { //定义静态函数 int n=10; cout< <
定义静态函数的好处:
静态数据成员
在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。
#includeusing namespace std;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="< <
可以看出,静态数据成员有以下特点:
int Myclass::Sum=0;
是定义静态数据成员(补充,也可以不赋初值)<数据类型> <类名> :: <静态数据成员名> = <值>值> 静态数据成员名> 类名> 数据类型>
<类对象名> . <静态数据成员名> // 或 <类类型名> :: <静态数据成员名>静态数据成员名> 类类型名> 静态数据成员名> 类对象名>
静态成员函数
与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,在静态成员函数中无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。下面举个静态成员函数的例子。
#includeusing namespace std;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< <
关于静态成员函数,可以总结为以下几点:
.
和->
为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用<类名>::<静态成员函数名>(<参数表>)
调用类的静态成员函数转载地址:http://iqsws.baihongyu.com/