C++的static关键字
来源:互联网 发布:mysql分组取前n条记录 编辑:程序博客网 时间:2024/05/16 15:19
一、面向过程设计中的static 1、静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下: 一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将 您可以将上述示例代码改为如下: 2、静态局部变量 在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。 我们先举一个静态局部变量的例子,如下: 静态局部变量有以下特点: 3、静态函数 在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。 静态函数的例子: 二、面向对象的static关键字(类中的static关键字) 1、静态数据成员 在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。 与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。 普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。 下面举个静态成员函数的例子。
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明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;}
静态全局变量有以下特点:
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:
代码区全局数据区堆区栈区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; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。//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;}
定义静态函数的好处://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();}
可以看出,静态数据成员有以下特点:
<数据类型><类名>::<静态数据成员名>=<值>
<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员 ;
2、静态成员函数//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();}
<类名>::<静态成员函数名>(<参数表>)
调用类的静态成员函数。
- C语言的static关键字
- C语言的static关键字
- C#: static关键字的作用
- 【C++】static关键字的作用
- C/C++的static关键字
- C#: static关键字的作用
- C#static关键字的作用
- static关键字的作用(c&&c++)
- C/C++static关键字的作用
- c/c++-----static关键字
- 【C/C++】关键字static
- c/c++static关键字
- C语言的static关键字的理解
- c语言中static 关键字的使用
- C语言关键字static的用法
- c语言的static和extern关键字
- C语言static关键字的若干问题
- c/c++中static关键字的作用
- Java 三大框架——SSH框架应用简介
- 使用native方法扩展Java程序的功能详解
- 冯·诺伊曼结构和哈佛结构
- ARM946es
- SQL--Cascading delete and update (Referential Integrity)
- C++的static关键字
- c程序内存分布
- 程序内存分布
- js this
- JVM参数对J2ee的影响
- 程序员常犯的5个非技术性错误
- 3步释放工作和生活压力
- 成为一名优秀程序员所需要知道的15件事
- Myeclipse中启动Tomcat服务出现Transport dt_socket failed to initialize,rc=509错误