一:为什么静态成员变量要通过类外初始化赋值?
当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关。
静态数据成员的用途之一是统计有多少个对象实际存在。
静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的。也不能在够造函数中初始化该成员,因为静态数据成员为类的各个对象共享,那么每次创建一个类的对象则静态数据成员都要被重新初始化。)
二:C++ class 全局变量的初始化
0、class类型的全局变量的构造函数在main()调用之前完成,有可能破坏构造函数中暗含的假设条件,例如gflags尚未初始化等。
1、禁止使用class类型的全局变量(包括STL中的vector,string等)
观点1:他们的初始化有可能导致构造出现问题。
观点2:全局变量的构造和析构和初始化操作的调用顺序只是被部分规定,每次生成有可能变化。对于不同编译单位的全局变量,其初始化的顺序没有任何的保证,因此对不同编译单位里的全局变量,在它们的初始化顺序之间建立依赖性都是不明智的。
2 永远不要使用函数返回至初始化全局变量。
3 如果要使用class全局变量,就使用单例模式(singleton pattern)。
4 静态成员变量视作全局变量,所以也不能是class类型 。
)
三、static全局变量/全局变量,static函数/普通函数,函数中static变量/函数中的变量,类中的static成员变量/类中的变量
static Global variable: 文件作用域:只在声明的文件中有效,其他源文件中不可见;同时有了static的生命周期
Global variable:文件作用域:可以加上extern 声明为外部变量,跨文件作用域
static (Global) Function: 有文件作用域,只在本文件中使用
Global Function:无文件作用域
static Member (in Function) variable:函数调用完成后,变量保存状态,再次调用函数,不会重新分配空间
Member(in Funcition) variable:函数内的生命周期
static Member(in Class) variable: 属于类范围,
Member(in Class) variable:属于类派生的特定对象,生命周期和对象一致
从作用域上来区分它们:
- 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。
- 局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
- 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
- 静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
从以上分析可以看出,把 局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。