在我看来,与Static有关的两个关键字是初始化和作用域,怎么理解呢?来看下面两个例子:
一、初始化
#include <stdio.h> #include <iostream> int main(void) { //int y; static int x; //printf("%d %d",x,y); printf("%d",x); }
以上代码中能够正确执行,在控制台中输出0,static int x语句做了两件事情:一、定义一个变量x;二、将变量x初始化为0。下面的代码发生了错误,提示变量在使用之前没有初始化。说明int x;仅仅定义了一个变量,没有初始化。静态变量就好像买房子,送家具,当然你也可以把家具换掉,普通变量声明,买房子没家具,你非要用里头没有的家具,就会出意外啊。
#include <stdio.h> #include <iostream> int main(void) { int y; static int x; printf("%d %d",x,y); //printf("%d",x); }
二、作用域
C++静态成员变量的作用域,使用static修饰的全局变量能够在各个函数内部被使用,但数不能在文件的外部被使用。这就是说,一般情况下同一工程中不同的cpp文件中的全局变量在编译的时候是彼此可见的,所以说,同一工程中,不能定义同名的全局变量,但是加入static关键字,就改变了static变量对于其它cpp文件的可见性,如果一个.cpp文件中使用static修饰全局变量,static int i;另一个文件中定义int i = 0的全局变量,则工程能够编译成功。
#include <stdio.h> #include <iostream> static int x = 5; int main(void) { printf("%d",x); }
上面的代码声定义一个静态全局变量x,在main函数内部也能够访问。
如果在函数中声明了一个静态变量并初始化,然后该函数被main函数多次调用,那么,函数会被定义初始化几次呢?答案是一次,不信?来看下面的例子。
#include <stdio.h> #include <iostream> using namespace std; static int x = 5; typedef void (FUNC)(); FUNC fn; int main(void) { for (int x = 0;x < 10; x++) { fn(); } } void fn() { static int i = 0; cout << "i = " << i++ << endl; }
typedef void (FUNC)();//定义一个函数类型
FUNC fn;生命一个函数fn
上面两句话等同于:但是FUNC是一个我们新定义的类型,可以用于定义其他符合类型的函数。
void fn();
运行上面的代码,输出:0,1,2,3,4,5,6,7,8,9。说明静态变量仅仅被定义和初始化一次。
总结:
1.静态全局变量,首先是全局变量,文件内部各个函数可见,由于static关键字的修饰,对其它cpp文件不可见.
2.函数内部定义的静态局部变量,仍然是局部变量,函数外部不可见;
3.静态全局变量,对于其它文件不可见;
4.静态变量无论初始化语句调用多少次,仅仅最初的一次初始化有效。
定义在类中的静态成员函数和静态成员变量的使用
定义在类中的静态成员变量的使用,例如可以同于统计实例化了多少个类,类中的静态成员变量在使用前同样必须进行初始化,初始化类的静态成员变量有两种情况:
类的静态常量:
在类的内部定义,可以在类的内部初始化。
在类的内部定义,不可以在内的内部初始化。
原因是静态变量属于类而不属于变量,而类内部定义的变量和函数必须实例化之后再内存中才存在,所以类的静态变量必须在类的外部初始化,而静态常量的存在不依赖于类,所以可以在类的外部初始化,语法为:int Point::m_nPointCount = 0,类似于cpp文件总函数的实现 。
static int m_nPointCount;//类的静态变量,不可以在类的内部初始化 const static int m_testInitial1 = 1;//类的静态变量,可以在类的内部初始化 static const int m_testInitial2 = 2;//类的静态变量,这种写法较为正常。
以下是一些C++类中变量的初始化规则。
1.除了静态全局变量,所有其它变量都不可以在定义的时候初始化。
2.常量数据成员,必须在构造函数成员列表中初始化
3.普通数据成员,可以在构造函数列表中初始化,也可以在构造函数内部初始化。
class initialVar{ public: static const int c = 0; int a,d; const int b; initialVar():b(1),d(0) { a =0; } };