C++类中的静态成员变量与静态成员函数
最近一直看c++相关的项目,但总是会被c++类中的静态成员变量与静态成员函数的理解感觉很是模糊,不明白为什么类中要是用静态成员变量.于是在网上搜集了一些资料,自己再稍微总结下。
静态成员的概念:
静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员先于类的声明而存在于内存,也可以根据类声明的对象来访问.而非静态成员必须实例化之后才会分配内存.
非静态成员的概念:
所有没有加static的成员都是非静态成员.而类被实例化后,可以通过实例化的类名进行访问.非静态成员的生存期决定于该类的生存期.而静态成员不存在生产期的问题,因为它始终驻留在内存.
分两个方面来总结,面向过程与面向对象.
一:面向过程中的static关键字
1.静态全局变量
定义全局变量前,加上关键字static,该变量就被定义成了一个静态全局变量.
特点:
- 该变量在全局数据区分配内存.
- 初始化:如果不是显示初始化,那么将被隐式初始化为0.
- 访变量只在本文件可见,即应该为定义之处开始到本文件结束.
程序在内存中一般分为四个区域:
- 代码区
- 全局数据区
- 堆区
- 栈区
一般程序由new产生的动态数据放在堆区,函数内部的自动变量放在栈区.自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)都存放在全局数据区.因此它们并不会随着函数的退出而释放空间.
static int n;//定义静态全局变量
改为: int n;//定义全局变量
区别:
静态全局变量不能被其他文件所用.因而其他文件可以定义相同名字的变量,而不会发生冲突.
例子:
//Example
//File 1
#include <iostream>
void fn();
static int n;//定义静态全局变量(只能在本文件中使用)
void main(){
n=20;
cout<<n<<endl;
fn();
}
//File 2
#include <iostream>
extern int n;(可在别的文件中引用这个变量)
void fn(){
n++;
cout<<n<<endl;
}//编译并运行Example,就会发现上述代码分别通过编译,但Link时会出错.
如果将static int n改为 :int n;
再次编译运行程序,就不会出错.
2.静态局部变量
在局部变量前加上static 关键字,就定义了静态局部变量.
特点:
A.该变量在全局数据区分配内存.
B.初始化时:如果不是显示初始化,那么将隐式初始化为0.
C.它始终驻留在全局数据区,直到程序结束.但其作用域为局部作用域.当定义它的函数或语句块时,其作用域随之结束.
3.静态函数:在函数的返回类型前加上static关键字.
特点:静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其他文件可用.
二:面向对象的static关键字
1.静态数据成员
在类中数据成员的声明前加上static,该成员是类的静态数据成员.
例子:
//example 2
#include <iostream>
class MyClass{
public:
MyClass(int a,int b,int c);
void GetSum();
private:
int a,b,c;
static int sum;//声明静态数据成员
};
int MyClass::sum=0;//定义并初始化静态数据成员
特点:
对于非静态数据成员,每个类对象都有自己的拷贝.而静态数据成员被当做是类的成员,无论这个类被定义了多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享(包括其派生类).所以,静态数据成员的值对每个对象都是一样的,它的值可以更新.
因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以它不属于特定的类对象,在没有产生类对象前就可以使用.
2.静态成员函数
与普通的成员函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针.从这个意义上来说,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,只能调用其他的静态成员函数.