当前位置:天才代写 > tutorial > C语言/C++ 教程 > C++的static要害字

C++的static要害字

2017-11-05 08:00 星期日 所属: C语言/C++ 教程 浏览:332

副标题#e#

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;
}

 

静态全局变量有以下特点:

该变量在全局数据区分派内存;

未经初始化的静态全局变量会被措施自动初始化为0(自动变量的值是随机的,除非它被显式初始化);

静态全局变量在声明它的整个文件都是可见的,而在文件之外是不行见的;  静态变量都在全局数据区分派内存,包罗后头将要提到的静态局部变量。对付一个完整的措施,在内存中的漫衍环境如下图:

代码区
全局数据区
堆区
栈区

一般措施的由new发生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会跟着函数的退出而释放空间,静态数据(纵然是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者大概会发明,Example 1中的代码中将

static int n; //界说静态全局变量

改为

int n; //界说全局变量

措施照样正常运行。


#p#副标题#e#

简直,界说全局变量就可以实现变量在文件中的共享,但界说静态全局变量尚有以下长处:

静态全局变量不能被其它文件所用;

其它文件中可以界说沟通名字的变量,不会产生斗嘴;

您可以将上述示例代码改为如下:

//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++;
}

#p#副标题#e#

凡是,在函数体内界说了一个变量,每当措施运行到该语句时城市给该局部变量分派栈内存。但跟着措施退出函数体,系统就会收回栈内存,局部变量也相应失效。

但有时候我们需要在两次挪用之间对变量的值举办生存。凡是的想法是界说一个全局变量来实现。但这样一来,变量已经不再属于函数自己了,不再仅受函数的节制,给措施的维护带来未便。

静态局部变量正好可以办理这个问题。静态局部变量生存在全局数据区,而不是生存在栈中,每次的值保持到下一次挪用,直到下次赋新值。

静态局部变量有以下特点:

该变量在全局数据区分派内存;

静态局部变量在措施执行到该工具的声明处时被首次初始化,即今后的函数挪用不再举办初始化;

静态局部变量一般在声明处初始化,假如没有显式初始化,会被措施自动初始化为0;

它始终驻留在全局数据区,直到措施运行竣事。但其浸染域为局部浸染域,当界说它的函数或语句块竣事时,其浸染域随之竣事;

3、静态函数

在函数的返回范例前加上static要害字,函数即被界说为静态函数。静态函数与普通函数差异,它只能在声明它的文件傍边可见,不能被其它文件利用。

静态函数的例子:

#p#分页标题#e#

//Example 4
#include <iostream.h>
static void fn();//声明静态函数
void main()
{
   fn();
}
void fn()//界说静态函数
{
   int n=10;
   cout<<n<<endl;
}

界说静态函数的长处:

静态函数不能被其它文件所用;

其它文件中可以界说沟通名字的函数,不会产生斗嘴;

#p#副标题#e#

二、面向工具的static要害字(类中的static要害字)

1、静态数据成员

在类内数据成员的声明前加上要害字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 5中,语句int Myclass::Sum=0;是界说静态数据成员;

静态数据成员和普通数据成员一样遵从public,protected,private会见法则;

因为静态数据成员在全局数据区分派内存,属于本类的所有工具共享,所以,它不属于特定的类工具,在没有发生类工具时其浸染域就可见,即在没有发生类的实例时,我们就可以操纵它;

静态数据成员初始化与一般数据成员初始化差异。静态数据成员初始化的名目为:

<数据范例><类名>::<静态数据成员名>=<值>

类的静态数据成员有两种会见形式:

<类工具名>.<静态数据成员名> 或 <类范例名>::<静态数据成员名>

假如静态数据成员的会见权限答允的话(即public的成员),可在措施中,按上述名目来引用静态数据成员 ;

静态数据成员主要用在各个工具都有沟通的某项属性的时候。好比对付一个存款类,每个实例的利钱都是沟通的。所以,应该把利钱设为存款类的静态数据成员。这有两个长处,第一,不管界说几多个存款类工具,利钱数据成员都共享分派在全局数据区的内存,所以节减存储空间。第二,一旦利钱需要改变时,只要改变一次,则所有存款类工具的利钱全改变过来了;

同全局变量对比,利用静态数据成员有两个优势:

静态数据成员没有进入措施的全局名字空间,因此不存在与措施中其它全局名字斗嘴的大概性;

可以实现信息埋没。静态数据成员可以是private成员,而全局变量不能;

#p#副标题#e#

2、静态成员函数

与静态数据成员一样,我们也可以建设一个静态成员函数,它为类的全部处事而不是为某一个类的详细工具处事。静态成员函数与静态数据成员一样,都是类的内部实现,属于类界说的一部门。普通的成员函数一般都隐含了一个this指针,this指针指向类的工具自己,因为普通成员函数老是详细的属于某个类的详细工具的。凡是环境下,this是缺省的。如函数fn()实际上是this->fn()。可是与普通函数对比,静态成员函数由于不是与任何的工具相接洽,因此它不具有this指针。从这个意义上讲,它无法会见属于类工具的非静态数据成员,也无法会见非静态成员函数,它只能挪用其余的静态成员函数。下面举个静态成员函数的例子。

//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();
}

关于静态成员函数,可以总结为以下几点:

呈此刻类体外的函数界说不能指定要害字static;

静态成员之间可以彼此会见,包罗静态成员函数会见静态数据成员和会见静态成员函数;

非静态成员函数可以任意地会见静态成员函数和静态数据成员;

静态成员函数不能会见非静态成员函数和非静态数据成员;

由于没有this指针的特别开销,因此静态成员函数与类的全局函数对比速度上会有少许的增长;

挪用静态成员函数,可以用成员会见操纵符(.)和(->)为一个类的工具或指向类工具的指针挪用静态成员函数,也可以直接利用如下名目:

<类名>::<静态成员函数名>(<参数表>)

挪用类的静态成员函数。

 

    关键字:

天才代写-代写联系方式