在C++中,static关键字有以下用法:
- 静态局部变量
- 静态全局变量
- 静态函数
- 类的静态成员变量
- 类的静态成员函数
以下对每种用法依次解释:
1.静态局部变量
a.静态局部变量在函数内定义,它的生存期为整个源程序,但是其作用域仍与普通变量相同,只能在定义该变量的函数内使用,退出该函数后,尽管该变量还继续存在,但不能使用它。
b.对基本类型的静态局部变量未赋以初值时,系统自动赋予0值。而对普通变量不赋初值,则其值是不定的。根据静态局部变量的特点,可以看出它是一种生存期为整个源程序的变量。虽然离开定义后他的函数后不能使用,但如在此调用定义它的函数,它又可继续使用,而且保存了前次被调用后留下的值。即静态局部变量不会因为函数的终止而丢失其值。因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。
栗子:
int fun(){
static int value = 1;
a++;
}//在第一次进入这个函数时,变量value被初始化为1,并接着自增1;以后每次调用该函数,value就不会再初始化,而是保持每次自增后的值。如第二次调用时,value = 2, 再自增1.
2.静态全局变量
全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。表明一个全局变量只对定义在同一文件中的函数可见。全局变量本身就是静态存储方式,静态全局变量自然也是静态存储方式。
a.区别在于非静态全局变量的作用域是整个源程序,当一个源文件由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。
b.而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。
从以上分析中看出,把局部变量改变为静态局部变量,是改变了它的存储方式即改变了其生命周期。把全局变量改变为静态全局变量是改变了其作用域,限制了它的使用范围。因此static这个说明符在不同的地方所以的作用是不同的。
3.静态函数
又称内部函数,声明方式如下:static 函数类型 函数名(参数);
静态函数(内部函数)只能被定义它的源文件使用,而不能被同一程序的其他文件中的函数调用。此处的static的含义又不是指存储方式,而是指对函数的作用域仅局限于本文件。
好处是:不用担心与其他文件中的函数同名,因为同名也没有关系。
4.类的静态成员变量
类的数据成员前加上static,即类的静态数据成员,表示对该类的所有对象,这个数据成员都只有一个实例。
因为静态成员不属于类的任何一个对象,所以它们并不是在创建类的对象是被定义的。这意味着它们不是由类的构造函数初始化的,而且一般来说,我们不能在类的内部初始化静态成员。相反的,必须在类的外部定义和初始化每个静态成员。
静态成员定义在任何函数之外,因此一旦定义,它将存在于整个程序的生命周期。
栗子:
class A{
private:
//类内声明
static int value;
};
//类的外部定义初始化
int A::value = 0;
类的静态成员是该类的所有实例共用成员,即在该类范畴内它是个全局变量。
注意:类的静态成员必须初始化。
5.类的静态成员函数
栗子:
class A{
private:
//类内声明
static void func();
};
//定义
void A::func(){
}
声明为静态成员函数意味着只能访问类的静态数据成员、全局变量和它自身传入的参数。
总的来说,静态成员函数具有以下特点:
- 静态成员函数之间可以相互访问,包括静态成员函数访问静态成员变量和访问静态成员函数;
- 非静态成员函数可以任意地访问静态成员函数和静态成员变量;
- 静态成员函数不能访问非静态成员变量和非静态成员函数;
- 由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许增长。