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