static存在的意义:
函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。
static的声明与定义:
静态数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员)。类声明只声明一个类的“尺寸和规格”,并不进行实际的内存分配,所以在类声明中写成定义是错误的。它也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。
static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,静态数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。
static使用时注意事项:
1. 当在类的外部定义static成员函数时,不需要重复指定static保留字,只出现在类定义体内部的声明处;
2. static成员是类的组成部分,但不是任何对象的组成部分;因此,static成员函数没有this指针。同时不能被声明为const,因为将成员函数声明为const就是承诺不会修改该函数所属的对象。;也不能被声明为virtual函数。
3. static数据成员必须在类定义体的外部定义。而不是通过构造函数初始化,一般在类成员实现文件中初始化;
4. 类的static成员,以及普通数据成员,不能在类的定义体中初始化!除了常量const!
5. const static 与 static const没有差别!
6. static数据成员的类型可以是该成员所属的类类型,同样是因为static数据成员不属于任何一个对象,在分配大小时,不需要考虑自身,考虑自身会出现死循环而导致出错。非static成员被限定声明为其自身类对象的指针或引用;
如:
class A
{
private:
static A a1; // OK
A * a2; // OK
A a3; // Wrong
}
7. static局部变量在程序执行第一次通过定义初始化,在程序结束前都不会被撤销。
8. 由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。由于静态成员函数没有this指针,所以就差不多等同于nonmember函数,结果就产生了一个意想不到的好处:成为一个callback函数,使得我们得以将C++和C-based X Window系统结合,同时也成功的应用于线程函数身上。 中有些例子可以帮助理解回调函数。
-------------------------------------------------------------
C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码
C++11 获取系统时间库函数 time since epoch
----------------------------------------------------------------------------
添加内容:
静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。