前言

经过static修饰的变量,存储在内存的全局静态区。且被static修饰的变量只能在本模块的所有函数引用。

内存中的存储区域如下:

堆区:是由程序员手动申请(new)与释放(delete)的内存区域。从低地址向高地址申请;内存空间大、存储地址不连续,一般是链式的;速度较慢。
栈区:由编译器自动分配和释放,主要存储 函数的参数值、函数内部的变量的值、函数调用的空间。从高地址向低地址申请;容量有限;速度较快;存储地址连续,会溢出。
代码区:又叫文本段(.text),存放着程序的机器代码,可执行指令就是存储在这里的,这里的代码是只读的。
全局区(静态区):全局变量和静态变量是存储在这里的。初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bbs)。系统结束后由系统释放。
常量区:常量字符串放在这里,程序结束后,由系统进行释放。

1. 概念

static的用法主要体现在两个方面:面向过程中的static和面向对象中的static。

面向过程的static主要包括静态全局变量、静态局部变量和静态函数。

面向对象的static主要包括静态成员变量、静态成员函数。

2. 面向过程的static

2.1 静态全局变量

全局变量前添加static关键字,则该变量称为静态全局变量。

#include <iostream>
#include <stdio.h>static int a = 10;void Func()
{a++;
}int main()
{printf("a = %d\n", a);//输出:10Func();//输出:10printf("a = %d\n", a);//输出:11system("pause");return 0;
}

特点:

1)在全局数据中的变量如果没有显示的初始化会自动被程序初始化为0(这个特性非静态全局变量也有),而在函数体内声明的变量如果不显示初始化则会使一个随机值;

2)静态全局变量在声明它的整个文件中都是可见的,而在文件之外是不可见的;

3)静态全局变量在全局数据区分配内存;

4)其他文件中可以定义同名int型变量a,不会冲突;

如果将static去掉,具有以下特点:

1)全局变量默认是有外部连接性的,其作用域是整个工程,在一个文件内定义的全局变量可以通过包含其所在头文件或显示调用 extern关键字修饰全局变量的变量名声明来引用;

2)静态全局变量是显示调用static修饰的全局变量,其作用域只在声明此变量的文件中,其他文件即使使用extern关键字修饰其声明也不可使用;

2.2 静态局部变量

局部变量前添加static关键字,则该变量称为静态局部变量。

#include <iostream>
#include <stdio.h>void Func()
{static int a = 5;printf("a = %d\n", a);a++;
}int main()
{for (int i = 0; i < 5; i++){Func();  //打印结果:5 6 7 8 9}system("pause");return 0;
}

通常,在一个函数作用域内定义一个变量,每次运行到该函数时,系统会给局部变量分配内存。当函数结束时,该变量的内存会被系统回收至栈内存当中。

特点:

1)内存存放在程序的全局数据区中;

2)静态局部变量在程序执行到该对象声明时,会被首次初始化。其后运行到该对象的声明时,不会再次初始化,这也是为什么上面程序测试函数每次输出的值都是递增的原因(只会被初始化一次)

3)如果静态局部变量没有被显式初始化,则其值会自动被系统初始化为0;

4)局部静态变量不能被其作用域之外的其他模块调用,其调用范围仅限于声明该变量的函数作用域当中;

2.3 静态函数

函数返回类型前添加static关键字,则该变量称为静态函数。

#include <iostream>
#include <stdio.h>static void Func()
{printf("This is a static function\n");
}int main()
{Func(); system("pause");return 0;
}

特点:

1)作用域只在声明它的文件当中,不能被其他文件引用,其他文件可以定义同名的全局函数;

2)其他文件想要调用本文件的静态函数,需要显示的调用extern关键字修饰其声明;

3. 面向对象中的static

3.1 静态成员变量

#include <iostream>
#include <stdio.h>
using namespace std;class Test
{
public:Test(int a, int b, int c) : m_a(a),m_b(b),m_c(c){m = a + b + c;}void Show(){cout << "m = " << m << endl;}private:int m_a, m_b, m_c;static int m;
};int Test::m = 0; //初始化静态数据成员int main()
{Test ClassA(1, 1, 1);ClassA.Show();  //输出: 3Test ClassB(3, 3, 3);ClassB.Show(); //输出: 9ClassA.Show(); //输出: 9system("pause");return 0;
}

特点:

1)静态数据成员的服务对象并非是单个类实例化的对象,而是所有类实例化的对象(这点可以用于设计模式中的单例模式实现);

2)静态数据成员必须显式的初始化分配内存,在其包含类没有任何实例化之前已经有内存分配;

3)静态数据成员与其他成员一样,遵从public,protected,private的访问规则;

4)静态数据成员内存存储在全局数据区,只随着进程的消亡而消亡

优势:

1)静态数据成员不进入程序全局命名空间,不会与其他全局名称的同名同类型变量冲突;

2)静态数据成员可以实现C++的封装特性,由于其遵守类的访问权限规则,所以相比全局变量更加灵活;

3.2 静态成员函数

类的成员函数返回类型之前添加static,此成员函数为静态成员函数。

#include <iostream>
#include <stdio.h>
using namespace std;class Test
{
public:Test(int a, int b, int c) : m_a(a),m_b(b),m_c(c){m = a + b + c;}static void Show(){cout << "m = " << m << endl;}private:int m_a, m_b, m_c;static int m;
};int Test::m = 0; //初始化静态数据成员int main()
{Test ClassA(1, 1, 1);ClassA.Show();Test ClassB(3, 3, 3);ClassB.Show();ClassA.Show();Test::Show(); //输出: 9system("pause"); return 0;
}

特点:

1)静态成员函数比普通成员函数多了一种调用方式;

2)在没有实例化的类对象的条件下可以调用类的静态成员函数;

3)静态成员函数中没有隐含的this指针,所以静态成员函数不可以操作类中的非静态成员(由于第二条可知,类的非静态成员是在类实例化后存在的,而类的成员函数可以在类没有实例化的时候调用,故不能操作类的非静态成员);

4. 总结

1)静态数据成员都是静态存储的,所以必须在main函数之前显示的对其进行初始化;

2)可以在头文件中声明静态全局变量,该头文件被多个cpp文件包含后,包含该头文件的cpp文件实际上会各自拥有独立的同名变量;

3)不能将静态成员函数定义为虚函数;

4)静态成员函数没有this指针;

5)static缩短了子类对父类静态成员访问的时间,相对来说节省了内存空间;

6)如果不想在子类中操作父类的静态成员,则可以在子类中定义一个同名的static成员。这样既可覆盖父类中的静态成员,并且根据C++的多态性变量命名规则,这样做是安全的;

7)静态成员声明在类中,操作在其外部,所以对其取地址操作就跟取普通成员的操作略有不同。静态变量地址是指向其数据类型的指针,函数地址则是一个类型为nonmember的函数指针;

c++——static总结相关推荐

  1. c语言中external,static关键字用法

    static用法: 在C中,static主要定义全局静态变量.定义局部静态变量.定义静态函数. 1.定义全局静态变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量.全局静态变量有 ...

  2. Exception in thread main java.lang.Error: 无法解析的编译问题: 方法 main 不能声明为 static;只能在静态类型或顶级类型中才能声明静态方法

    Exception in thread "main" java.lang.Error: 无法解析的编译问题: 方法 main 不能声明为 static:只能在静态类型或顶级类型中才 ...

  3. Static interface methods are only supported starting with Android N (--min-api 24): void okhttp3.log

    错误内容如下 Error: Static interface methods are only supported starting with Android N (--min-api 24): vo ...

  4. Java 静态变量,静态方法,静态常量(java static 关键字)

    Java 静态变量,静态方法,静态常量  就是变量 ,方法,常量前面添加了static 关键字 为什么要使用静态的呢 有时候在处理问题时会需要两个类在同一个内存区域共享一个数据, 不如现在 Main ...

  5. java static 作用详解

    static表示 "静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,也可是修饰内部类, 我们常说的静态内部类,注意外部类不能使用静态的, static方 ...

  6. public static final int REMIN_REQUEST_CODE = 0x911 自己的大致理解

    public static final int REMIN_REQUEST_CODE = 0x911; 自己理解为 一个静态常量,也就一个标识,自己目前主要在2个地方常用到 OnActivityRes ...

  7. C++ static

    (1)static表示静态变量.局部变量存储在栈区,在{}结束时被释放.而static修饰的变量存储在全局区,在程序结束时被释放. (2)static修饰的变量在外部文件中无法调用,即使使用exter ...

  8. java static 可见性_Java多线程 synchronized与可见性的关系以及可见性问题总结

    作者:七里香的编程之路 出自:OSCHINA 原文:my.oschina.net/u/4098550/blog/4548274 能保证可见性的措施 除了volatile 可以让变量保证可见性外.hap ...

  9. c cin.get()的用法小结_c语言中static 用法

    static在c里面可以用来修饰变量,也可以用来修饰函数. 先看用来修饰变量的时候.变量在c里面可分为存在全局数据区.栈和堆里.其实我们平时所说的堆栈是栈而不是堆,不要弄混. int a ; int ...

  10. java内部类的权限符,static介绍、内部类、final、权限修饰符的作用范围,

    static介绍.内部类.final.权限修饰符的作用范围,static 关键字:(可用于修饰方法.变量) static 特点: static是静态修饰符,一般修饰成员变量.被static修饰的属于全 ...

最新文章

  1. PATH、cp命令、mv、文档查看命令
  2. AngularJS track by $index引起的思考
  3. php Immutable,Immutable.js详解
  4. [转载] 50个数据可视化最有价值的图表(附完整Python代码,建议收藏)
  5. mvn命令传递参数和pom文件配置的关系
  6. 代码管理学:安排新员工看代码,因为主管不会管理,不负责任
  7. 求求你,千万别为我好!
  8. mysql 主从复制延迟_什么情况会导致MySQL主从复制延迟?
  9. 盘点丨12款数据库建模工具特点,总有一款适合你!
  10. VMware虚拟机安装黑群晖7.0教程
  11. 普通代码签名证书和EV代码签名证书的区别
  12. win7远程服务器管理工具
  13. 【鼠标右键点击桌面图标时,出现资源管理器未响应】
  14. 张良、萧何与韩信:汉初三杰悲情录[转]
  15. py2exe找不到Python的解决方法
  16. 手机上安装FTP服务器,通过FTP实现计算机上用FTP客户端对手机文件的无线连接访问
  17. 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解
  18. 计算机音乐-乐理知识(1)
  19. 顺顺网页电子表格控件开源下载
  20. 引擎TA校园招聘: 搜狐畅游 追光者计划简介

热门文章

  1. 三大框架之spring框架+IoC控制反转、DI依赖注入
  2. new game 1.0
  3. 霍纳法树形流图中处理机p个数_计算机系统结构习题课
  4. Glide源码分析3 -- 绑定Activity生命周期
  5. java dom遍历_jQuery DOM节点的遍历
  6. P2P平台借款人与债权人的匹配原理
  7. 地摊经济大火之后,如何从零开始摆摊创业?
  8. USB驱动程序之USB设备驱动程序1简单编写
  9. 任务调度神器 airflow 之初体验
  10. 能带你起飞的【数据结构】成王第一篇:数据结构的顺序表