隐藏-所有不加static的全局变量和函数具有全局可见性,可以在其他文件中使用,加了之后只能在该文件所在的编译模块中使用,即内部连接默认初始化为0,包括未初始化的全局静态变量与局部静态变量,都存在全局未初始化区静态变量在函数内定义,始终存在,且只进行一次初始化,具有记忆性,其作用范围与局部变量相同,函数退出后仍然存在,但不能使用。
static成员变量:只与类关联,不与类的对象关联。定义时要分配空间,不能在类声明中初始化,必须在类定义体外部初始化,初始化时不需要标示为static;可以被非static成员函数任意访问。
static成员函数:不具有this指针,无法访问类对象的非static成员变量(可以通过对象访问)和非static成员函数;不能被声明为const、虚函数和volatile;可以被非static成员函数任意访问。
面试过程中,如果你能够答出上面的知识点,那么恭喜你,基本掌握static的特点,但过于表面。面试官可能会继续追问你:
简单来说就是static修饰的局部静态变量附近**存放着1字节的标识位(最多可以标识8个静态变量)用来标识该变量是否初始化**。此外,**编译器还会在标识位附近加锁用来保证局部静态变量的初始化线程安全**。
静态成员变量属于类,而不属于对象,因此,静态成员变量只有一份副本,不像非静态成员变量那样每个对象都拥有自己的一份。**如果在类声明中初始化,那么可能就会出现重复初始化,导致链接的时候报错**,所以在类外初始化主要是为了保证只初始化一次。
可以从生命周期上来切入,**首先静态局部变量的生命周期是从第一次执行到定义静态局部变量的语句时到程序结束,**所以可以设置标识位来避免重复定义。**而静态成员对象的生命周期和类声明周期一样,程序开始到程序结束,在编译期间就已经为静态成员变量分配内存了,所以没办法进行判断**。换句话说,静态局部变量可以理解为运行时,当然可以校验标识位,**但是静态成员变量是编译时,逻辑已经固定,不存在动态来判断标识位。**
`const`:const 成员函数是用来保证对象的常量性不变,即在该函数中不会修改对象的成员变量。**但是 static 成员函数并不依赖于特定的对象,它只是属于类本身,因此没有必要将其声明为 const**。 `virtual`:virtual 是用来实现多态的关键字,它只适用于非静态成员函数。**static 成员函数不依赖于任何对象,也就无法实现多态特性,因此不能被声明为virtual。** `volatile`:volatile 关键字用于指示编译器在优化代码时不应该对变量进行缓存或优化。**但是 static 成员函数并不访问任何对象的状态,也不受任何对象状态的影响,因此没有必要使用 volatile 修饰符。**
首先,在类定义体里面定义函数,**默认都是内联的,内联函数就是在调用该函数出进行插入代码段,所以不会出现重复定义的问题**。