Static用法

一、面向过程设计中的static

1、  静态全局变量:

对于一个完整的程序,在内存中的分布情况如下图:

  代码区 //low address

  全局数据区

  堆区

  栈区 //high address

一般程序把新产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。

 

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

(1)该变量在全局数据区分配内存;

(2)未经初始化的静态全局变量会被程序自动初始化为0( 在函数体内声明的自动变量的值是随机的,除非它被显式初始化,而在函数体外被声明的自动变量也会被初始化为0);

(3)静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;

2、静态局部变量

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

(1)该变量在全局数据区分配内存;   

(2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;   

(3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;   

(4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

3、静态函数

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

其它文件中可以定义相同名字的函数,不会发生冲突;

 

二、面向对象的static关键字(类中的static关键字)

1、  静态数据成员:

对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷 贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共 用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;

静态数据成员和普通数据成员一样遵从public,protected,private访问规则;   

因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;   

静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:   <数据类型><类名>::<静态数据成员名>=<值>

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

(1)       出现在类体外的函数定义不能指定关键字static;   

(2)       静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;   

(3)       非静态成员函数可以任意地访问静态成员函数和静态数据成员;   

(4)       静态成员函数不能访问非静态成员函数和非静态数据成员;   

(5)       由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;

 

3、注意事项:

(1)类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数。   

(2)不能将静态成员函数定义为虚函数。   

(3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。   

(4)由于静态成员函数没有this指针,所以就差不多等同于nonmember函数,结果就产生了一个意想不到的好处:成为一个callback函数,使得我们得以将C++和C-based X Window系统结合,同时也成功的应用于线程函数身上。   

(5)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问时间,节省了子类的内存空间。   

(6)静态数据成员在<定义或说明>时前面加关键字static。   

(7)静态数据成员是静态存储的,所以必须对它进行初始化。   

(8)静态成员初始化与一般数据成员初始化不同:   

初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;   

初始化时不加该成员的访问权限控制符private,public等;   

初始化时使用作用域运算符来标明它所属类;   

所以我们得出静态数据成员初始化的格式:<数据类型><类名>::<静态数据成员名>=<值>   (9)为了防止父类的影响,可以在子类定义一个与父类相同的静态变量,以屏蔽父类的影响。这里有一点需要注意:我们说静态成员为父类和子类共享,但我们有重复定义了静态成员,这会不会引起错误呢?不会,我们的编译器采用了一种绝妙的手法:name-mangling 用以生成唯一的标志。在各通信公司的笔试面试中经常出现的考题就是static的作用及功能。

 

三、static修饰变量与函数的作用

(1)       缩小作用域:当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。使用static修饰全局变量很函数以后,其只能在当前文件域内可见。

(2)       使变量内容寿命延长:由于static修饰的变量 (全部或局部)存储在静态数据区,该变量会在程序开始运行时就完成初始化,也是唯一一次的初始化。共有两种变量存储在静态存储 区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围。

(3)       修饰变量默认初始化为0。

posted @ 2012-05-21 18:07  always on the way  阅读(378)  评论(0编辑  收藏  举报