首页 > 代码库 > C++类中的静态成员变量与静态成员函数

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指针.从这个意义上来说,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,只能调用其他的静态成员函数.

 

C++类中的静态成员变量与静态成员函数