参考:C++中类的(static)静态成员变量与(static)静态成员函数
一、static修饰全局变量
在全局变量前加static,全局变量就被定义成为一个全局静态变量。
- 特点如下:
- 存储区:静态存储区没变(静态存储区在整个程序运行期间都存在);
- 作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。非静态全局变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
- 好处:
- 不会被其他文件所访问,修改;
- 其他文件中可以使用相同名字的变量,不会发生冲突。
二、static修饰局部变量
在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。
- 特点如下:
- 存储区:由栈变为静态存储区rw data,生存期为整个源程序,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它;
- 作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。
三、static修饰函数
在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用
- 好处:
- 其他文件中可以定义相同名字的函数,不会发生冲突
- 静态函数不能被其他文件所用。
四、static修饰成员变量
-
静态成员变量属于整个类所有
-
静态成员变量的生命期不依赖于任何对象,为程序的生命周期
-
可以通过类名直接访问公有静态成员变量,非静态成员函数也可以访问静态成员变量(例如定义一个静态成员变量作为计数器)
-
所有对象共享类的静态成员变量
-
可以通过对象名访问公有静态成员变量
-
静态成员变量需要在类外单独分配空间
-
静态成员变量在程序内部位于全局数据区
-
初始化:
Type className::VarName = value
(在类外初始化,注意要带类型)
五、static修饰成员函数
-
静态成员函数是类的一个特殊的成员函数
-
静态成员函数属于整个类所有,没有this指针,因此静态成员函数不可以调用类的非静态成员
-
静态成员函数只能直接访问静态成员变量和静态成员函数,或者也可以访问全局变量
-
可以通过类名或对象名直接访问类的公有静态成员函数
-
静态方法可以被类直接调用,但是同静态变量一样符合public、private、protect特性
-
private static 是私有的,只能通过类的成员函数访问,可以是普通成员函数也可以是静态成员函数。不能直接通过ClassName::访问。
-
静态成员函数不可以同时声明为 virtual或后缀const 函数。因为virtual就是用来区分是哪个对象调用了他,与静态方法矛盾。而后缀const是用来修饰this指针的,静态变量中不包含this指针
-
调用静态方法不会调用构造函数
描述 | 静态成员函数 | 普通成员函数 |
---|---|---|
所有对象共享 | yes | yes |
隐含this指针 | no | yes |
访问普通成员变量(函数) | no | yes |
访问静态成员变量(函数) | yes | yes |
通过类名直接调用 | yes | no |
通过对象名直接调用 | yes | yes |
其他
1.DLL中不要使用static
不要在动态库中使用static,static声明的变量初始化,只是在程序运行的第一次被执行。但是动态库在每次加载时都会被执行,程序运行一次,但是dll可能被加载多次,本质就是static声明的变量的生命周期与包含它的组件相关。
2.static和匿名空间与匿名枚举的区别
namespace,匿名命名空间比static更好使,也不容易出错,推荐使用匿名命名空间。