static全局变量和普通全局变量
相同点:
存储方式:普通全局变量和static全局变量都是静态存储方式
不同点:
作用域:普通全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都是有效的;静态全局变量则是限制了其作用域,在同一源程序的其他源文件中不能使用它,由于静态全局变量的作用域限于一个源文件,只能为该源文件内函数公用,因此可以避免其他源文件中引起错误
初始化:
1.修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在main函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认的值初始化它。
2.用static声明局部变量(局部变量指在代码块 {} 内部定义的变量,只在代码块内部有效(作用域)),用static声明局部变量时,则改变变量的存储方式(生命期),使变量成为静态的局部变量,即编译时就为变量分配内存,直到程序退出才释放存储单元。这样,使得该局部变量有记忆功能,可以记忆上次的数据,不过由于仍是局部变量,因而只能在代码块内部使用(作用域不变)。
3.修饰成员变量,在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性,因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员,对于多个对象来说,静态数据成员只存储在一处,共所有对象公用。
4.修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用,在多人开发项目时,为了防止与他人命名空间里的函数重名,可以将函数定位为static
5.修饰成员函数,静态成员函数与静态数据成员一样,它们都属于类的静态成员,而不是对象成员,因此对静态成员的引用不需要对象名,在静态成员函数中的实现不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员函数中要引用非静态成员时,可通过对象来引用,从中可看出,调用静态成员函数使用如下格式<类名>::<静态成员函数名>(<参数表>)
静态变量的内存分配和初始化
C++引入了对象,这给全局变量的管理带领新的麻烦。C++的对象必须有构造函数生成,并最终执行析构操作。由于构造和析构并非分配内存那么简单,可以说相当复杂,因此何时执行全局或静态对象(C++)的构造和析构呢?这需要执行相关代码,无法在编译期完成,因此C++标准规定:全局或静态对象当且仅当对象首次用到时才进行构造,并通过atexit()来管理对象的生命期,在程序结束之后(如调用exit,main),按FILO顺序调用相应的析构操作!
总结:
全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义类型的对象。
static静态成员变量:
1.静态成员变量是在类内进行声明,在类外进行定义和初始化,在类外进行定义和初始化的时候不要出现static关键字和private,public,protected访问规则
2.静态成员变量相当于类域的全局变量,被类的所有对象所共享,包括派生类的对象
3.静态成员函数可以作为成员函数的参数,普通成员变量不可以
4.静态数据成员的类型可以是所属类的类型,而普通数据成员的类型只能是该类类型的指针或引用
static静态成员函数
1.静态成员函数不能调用非静态成员变量或者非静态成员函数,因为静态成员函数没有this指针,必须通过类名才能访问,静态成员函数作为类作用域的全局函数
2.静态成员函数不能声明为虚函数,const函数和volatile函数