static关键字主要分为四大点:static修饰全局变量,static修饰局部变量,static修饰静态成员变量,static修饰静态成员函数
static修饰普通变量有两种情况:全局变量和局部变量
在全局变量前加上一个static关键字,普通全局变量就变成一个静态全局变量,我们主要从三个方面来进行说明:存储,初始化和作用域
存储
介绍存储之前,我们首先需要了解数据在内存中的存储结构,存储结构图如下
静态全局变量都存储在静态存储区(data段的ro段或者BSS段)。未初始化的静态全局变量存储在BSS段。初始化了的静态全局变量存储在data段的ro段,并且静态全局变量和普通全局变量一样,在整个程序运行期间会一直存在。
初始化
未经初始化的全局变量会被系统自动初始化为0
作用域
普通局部变量加上static关键字修饰后,变成静态局部变量,我们仍然从三个方面来进行说明:存储,初始化和作用域
静态局部变量存储在静态存储区,和静态全局变量一样,初始化了的静态局部变量存储在data段的ro段,没有初始化的静态局部变量存储在BSS段。
未经初始化的全局静态变量会被自动初始化为0。
静态局部变量作用域仍然为局部作用域。当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,没有销毁,而是留在内存块中,只是我们不能再对其进行访问。直到函数再次被调用,并且静态局部变量的值是不变的。
static可以实现在同一个类中,不同对象之间实现数据共享、协调工作。
静态变量有全局变量的优势,但不会被全局变量一样被滥用,而用于管理静态变量。
类的静态成员。属于类,也属于对象,但终究属于类。
在类的数据成员前加上关键字static,类的数据成员就成为静态数据成员,我们主要从五个方面来进行说明:共享、初始化、类大小、存储、访问
共享
设置静态数据成员,可以实现在同一个类中,不同对象之间实现数据共享
在类外定义,定义格式:数据类型类名::数据变量=初始化的值
类大小
存储在静态存储区data段的ro段。
访问
可以通过对象访问,也可以通过类名访问。类的静态数据成员,属于类,也属于对象,但终究属于类。
之前我们已经了解到,类的静态成员变量是可以在没有对象的情况下进行访问的,因此要访问类的静态成员变量的函数也要能实现在没有对象的时候访问。为了实现这样的情况,我们可以把访问静态数据成员的函数设置为静态成员函数。static修饰类的成员函数,主要用来管理静态数据成员。
静态成员函数的意义,不在于信息共享,而在于管理静态数据成员,完成对静态数据成员的封装
static只能访问静态数据成员而不能访问非静态数据成员。因为非静态数据成员在调用时this指针被当做参数传入。而静态成员函数属于类,而不属于对象,没有this指针
非静态成员函数可以访问静态成员函数。
对于static关键字中类的成员来说,我们可以举一下的例子进行说明
要实现不同乘除法实现求和,我们可以考虑类的构造函数以及静态数据成员的特性:静态数据成员在同一个类中、多个对象之间实现数据共享。
由于每创造一个对象就会调用一次构造函数,因此我们可以设置一个静态数据成员,然后每次调用递加一次
1classSolution{2public:3//可以利用构造函数来实现不用加减乘除做加法4/*5利用类的静态成员变量中static特性。static修饰类的数据成员变量,可以实现数据成员变量在类中的不同对象之间的数据共享6因此我们可以在构造函数中使用这个静态成员变量,由于创建每个数据成员都会调用其构造函数,即可以实现相加7*/8classtemp9{10public:11temp()12{13++N;14sum+=N;15}16staticvoidreset()17{18N=0;19sum=0;20}21staticintgetsum()22{23returnsum;24}2526private:27staticintN;28staticintsum;29};3031intSum_Solution(intn){32temp::reset();33temp*a=newtemp[n];34delete[]a;35a=nullptr;36returntemp::getsum();37}38};39intSolution::temp::N=0;40intSolution::temp::sum=0;