C++中的static

C++中的static

1.过程中的中的static

静态全局变量(在全局变量前加static)

#include <iostream>
using namespace std;
void fn();

static int n;//static globle var

int main()
{
	n=20;
	cout<<n<<endl;
	fn();
}

void fn()
{
	n++;
	cout<<n<<endl;
}

 

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

  • 未经初始化的静态全局变量被程序自动初始化为0;
  • 静态全局变量在整个文件中都是可见的,而在文件之外是不可见的;

以上代码中,如果把static去掉,照样运行正常。的确,定义全局变量可以用在整个文件中共享,但定义全局变量还有以下好处:

  • 静态全局变量不能被其它文件所用,其它文件定义相同的名字不会发生冲突。

注意全局变量和全局静态变量的区别:

  • 全局变量不加static修饰,但全局变量默认是静态的,作用于整个工程,在一个文件中定义全局变量,在另一个文件中用extern 全局变量声明,就可以使用全局变量。
  • 全局静态变量显示用static修饰,但是他作用于它所在的文件中,对于其它文件不可引用,即使用extern也无法引用它。

 

静态局部变量(在一个局部变量前加static)

#include <iostream>
using namespace std;

void fn();

void main()
{
	fn();
	fn();
	fn();
}

void fn()
{
	static int n=10;
	cout<<n<<endl;
	n++;
}

 

通常局部变量在函数完毕后变会被释放,基值不在保存。但是我们如果需要在两次调用的时候保存变量的值,通常的方法定义一个全局变量来实现,但是这样一来,变量不在属于函数本身了,而属于整个文件,给维护带来很多问题。静态局部变量可以很好的解决这个问题。

静态局部变量保存的全局数据区,而不是保存在栈上,每次的值保存到下一次调用,直到下一次赋新值。

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

  • 该变量在全局数据区分配内存;
  • 它在执行到该对象首次声明处被首次初始化,即以后调用函数不再初始化。
  • 它一般在声明处初使化,如果没有显示初始化,则被初始化为0。
  • 它始终驻留于程序中,直到程序结束运行。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束

静态函数(在函数返回值前面加static)

说明:它与变通函数不同,它只能在声明它的文件中可见,不能被其它文件使用。

好处:

  • 不能被其它文件所用;
  • 其它文件中定义同名函数,不会发各冲突。

2.面向对象中的static关键字(类中的static)

静态数据成员:

// static_class_data_member.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

class Myclass
{
public:
	Myclass(int a,int b, int c);
	void GetSum();
private:
	int a,b,c;
	static int Sum;//it's a static class data member
};

int Myclass::Sum=0;//definition and initial the static class data member
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;
}
int _tmain(int argc, _TCHAR* argv[])
{
	Myclass M(1,2,3);
	M.GetSum();
	Myclass N(4,5,6);
	N.GetSum();
	M.GetSum();
	return 0;
}

可以看出静态数据成员有以下特点:

  • 对于非静态数据成员,第一个类对象都有自己的一份拷贝。而静态类成员被当作是类的成员,无论这个对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型所有对象共享访问。也就是说,静态数据成员间该类的所有对象所共有的,对于类的多个对象来说,静态数据礔 只分配一次内存,供所有对象共用,所以,静态数据成员产的值对每天个对象都是一样的,它的值可以更新。
  • 静态数据成员在全局数据区。静态数据成员在定义时要分配空间,所以不能在类声明中定义,在上例中,语句int Myclass::Sum=0;是定义静态数据成员。
  • 静态数据成员和普通数据成员一样,遵从public,protected,private访问规则。
  • 因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定类对象,在没有产生类对象的时候它的作用域就已经可见了,即在没有产生类实例的时候,我们就可以操作它。
  • 静态数据成员与一般的数据初使化不同,格式化为:
  • <数据类型><类名>::<成员名>=<值>
  • 类的静态数据成员访问有两种形式:
  • <类对象名>.<静态数据成员名>或<类类型名>::<静态数据成员>
  • 如果静态数据成员的访问权限允许的话(public),按上述格式引用静态数据成员。
  • 静态成员变量主要在各个对象都有相同的某项属性的时候。比如对于一个存款类,每一个实例的利息都是相同的,所以应该把利息设为存款类的静态数据成员。这有两个好处和:第一、不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区内存,所以节省存储空间。第二,一但利息需要改变时,只要改变一次就行了。
  • 同全局变量相比,使用静态数据成员有两个优势:
  • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性。
  • 可以实现信息的隐藏。静态数据成员可以是private成员,而全局变量不能。

静态成员函数

与静态数据成员一样,静态成员函数不是专们为某一相类对象而服务的,而是为此类的全部对象所服务。它不与任意类对象所联系,所以它不具有this指针。从这个意义上讲,它无法访问非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。

#include <iostream>

using namespace std;

class Myclass
{
public:
	Myclass(int a,int b,int c);
	static void GetSum();//static class_member fun
private:
	int a,b,c;
	static int Sum;//static class_member_data
};

int Myclass::Sum=0;//definition and initialization
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;
}

int main()
{
	Myclass M(1,2,3);
	M.GetSum();
	Myclass N(4,5,6);
	N.GetSum();
	Myclass::GetSum();
}

关于静态成员函数,有以下特点:

  • 出现在类体外的函数定义不能指定关键字static;
  • 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数。
  • 静态成员函数不能访问非静态函数和非静态数据成员。
  • 由于没有this指针的额外开销,因此静态成员函数与类全局函数相比速度会有少许增长。
  • 调用:<类名>::<静态成员函数名>(<参数表>)

作用:

static静态变量声明符。在声明它的程序块,子程序块或函数内部有效,值保持在整个程序期间分配存储品空间,编译器默认值0。

是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

posted @ 2011-07-09 11:02  瓜蛋  阅读(416)  评论(0编辑  收藏  举报