C++static关键字
static关键字
- 面向对象 (变量、函数)
- 静态成员变量
- 静态成员函数
- 面向过程
- 静态全局变量
- 静态局部变量
- 静态函数
静态成员变量
在类内成员变量的声明前加上关键字static,该数据成员就是类内的静态数据成员。
静态成员变量特点:
- 静态成员变量是该类的所有对象所共有的。对于普通成员变量,每个类对象都有自己的一份拷贝。而静态成员变量一共就一份,无论这个类的对象被定义了多少个,静态成员变量只分配一次内存,由该类的所有对象共享访问。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;
- 因为静态数据成员在全局数据区分配内存,由本类的所有对象共享,所以,它不属于特定的类对象,不占用对象的内存,而是在所有对象之外开辟内存,在没有产生类对象时其作用域就可见。因此,在没有类的实例存在时,静态成员变量就已经存在,我们就可以操作它;
- 因为静态成员变量 不随 一个类的实例化 而重新开辟内存。所以 静态成员变量,必须在类外定义,如例子中的
int Myclass::Sum;
在这儿定义了之后,才会被分配内存,因此不定义的话就会报错。但是可以不初始化,静态成员变量存储在全局数据区,编译器就默认0. - static 成员变量和普通 static 变量一样,编译时在静态数据区分配内存,到程序结束时才释放,不随对象的销毁而释放内存。
- 静态成员变量定义 初始化 可以不加 static 关键字 如例子。
<数据类型><类名>::<静态数据成员名>=<值>
- 静态成员变量可以不通过 类对象 访问
sizeof
运算符不会计算 静态成员变量- 静态数据成员和普通数据成员一样遵从public,protected,private访问规则;
### 应用场景
如果想在同类的多个对象之间实现数据共享,又不要用全局变量,那么就可以使用静态成员变量。静态数据成员主要用在各个对象都有相同的某项属性的时候。比如对于一个存款类,每个实例的利息都是相同的。所以,应该把利息设为存款类的静态数据成员。这有两个好处:
- 不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区的内存,节省存储空间。
- 一旦利息需要改变时,只要改变一次,则所有存款类对象的利息全改变过来了。
相对全局变量的优点
- 静态成员变量没有进入程序的全局命名空间,因此不存在与程序中其它全局命名冲突的可能。
- 可以实现信息隐藏。静态成员变量可以是private成员,而全局变量不能。
1 | class CMyclass{ |
1 | class Myclass |
静态成员函数
与静态成员变量类似,我们也可以声明一个静态成员函数。
特点
- 出现在类体外的函数定义不能指定关键字static; (就是static关键字只能出现在类里)
- 静态成员之间可以相互访问,即静态成员函数(仅)可以访问静态成员变量、静态成员函数;
- 静态成员函数不能访问非静态成员函数和非静态成员变量;
- 非静态成员函数可以任意地访问静态成员函数和静态数据成员;
- 由于没有this指针的额外开销,静态成员函数与类的全局函数相比速度上会稍快; (也正是因为没有this指针,静态成员函数不能访是虚函数,也不能访问非静态成员)
- 调用静态成员函数,两种方式 通过对象 和 不通过对象 调用
拷贝构造函数的问题
例如下面的例子中,调用拷贝构造函数生成临时隐藏类对象时,这个临时对象在消亡时会调用析构函数 会 执行 totle_num–。简言之,就是在使用 拷贝构造时 对静态成员变量的操作要注意时 成对的 否则会出bug
1 | //Example 6 |
静态全局变量
特点
- 该变量在全局数据区分配内存;
- 未经初始化的静态全局变量会被程序自动初始化为0(自动变量的自动初始化值是随机的);
- 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;
对于一个完整的程序,在内存中的分布情况如下:
【代码区】【全局数据区】【堆区】【栈区】
堆区:一般程序的由new产生的动态数据存放在 栈区:函数内部的自动变量存放在栈区,自动变量一般会随着函数的退出而释放空间 全局数据区:静态数据(即使是函数内部的静态局部变量)存放在全局数据区。而全局数据区的数据并不会因为函数的退出而释放空间。
优点
- 静态全局变量不能被其它文件所用;(即使在其它文件中使用extern 进行声明也不行)
- 其它文件中可以定义相同名字的变量,不会发生冲突;
静态局部变量
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,这给程序的维护带来不便。静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
特点
- 静态局部变量在全局数据区分配内存;
- 静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
- 静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
- 静态局部变量始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;
静态函数
在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。
- 静态函数不能被其它文件所用;
- 其它文件中可以定义相同名字的函数,不会发生冲突;