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++中很常用的修饰符,它被用来控制变量的存储方式和可见性。
本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段。c++/lua/windows逆向交流群:69148232