static用法

  static 这个知识点很老套啦,但是基本上能够说全的很少,要深入理解的话,需要实际的开发经验才行。

  在讲解分析static的作用的时候,先来了解程序的空间的分配,我们知道,在程序中,常用的内存类型有堆、栈和静态存储区:

  •  堆:由程序员自己分配释放(用malloc和free,或new和delete) ,如果我们不手动释放,那就要到程序结束才释放。如果对分配的空间在不用的时候不释放而一味的分配,那么可能会引起内存泄漏,其容量取决于虚拟内存,较大。
  •  栈:由编译器自动分配释放,其中存放在主调函数中被调函数的下一句代码、函数参数和局部变量,容量有限,较小。
  •  静态存储区:由在编译时由编译器分配,由系统释放,其中存放的是全局变量、static变量和常量.
  堆、栈和静态存取区有如下区别:
  •  堆是由低地址向高地址扩展,栈是由高地址向低地址扩展。
  •  堆是不连续的空间,栈是连续的空间。
  •  在申请空间后,栈的分配要比堆的快。对于堆,先遍历存放空闲存储地址的链表、修改链表、再进行分配;对于栈,只要剩下的可用空间足够,就可分配到,如果不够,那么就会报告栈溢出。
  •  栈的生命期最短,到函数调用结束时;静态存储区的生命期最长,到程序结束时;堆中的生命期是到被我们手动释放时(如果整个过程中都不手动释放,那就到程序结束时)。
  在C语言中,static 的作用有3点:

  1、扩展局部变量的生存周期

  使用static 关键字修饰的局部变量,其生存周期不再是当前作用域,而是整个程序的生存周期。C/C++中,局部变量按照存储形式可以分为三种:auto,static和register:

  auto的含义是由程序自动控制变量的生存周期,通常是变量进入作用域的时候被分配内存空间,离开其作用域的时候其内存空间被释放。

  static 变量,不管是局部的还是全局的,都放在静态存储区,变量在初始化的时候被分配内存空间,直到程序退出时,其内存空间才被释放。即static变量的生命周期是整个程序的生命周期。static变量在执行main函数前就已经被初始化,是在程序初始化的时候被分配内存空间的。局部变量的默认类型都是auto,从栈中分配内存。

  2、限制作用域

  这是相对于普通全局变量和static 全局变量来说的。对于全局变量而言,不论是普通全局变量还是static 全局变量,其存储区都是静态存储区,因此在内存分配上没有什么分别,其区别在于:

  1)普通全局变量或函数,其作用域是整个程序或项目,外部文件(即其他cpp文件)可以通过extern 关键字访问该变量和函数。一般不提倡这种做法,如果要在多cpp文件中共享数据,应该将数据声明为extern 类型。在头文件里声明extern 的方式如下:

      extern int g_value;    //注意不要初始化值!

然后在其中任何一个包含该头文件的cpp中初始化一次即可:

      g_value = 0;       //// 初始化一样不要extern修饰,因为extern也是声明性关键字;然后所有包含该头文件的cpp文件都可以用g_value这个名字访问相同的一个变量;

  2)static全局变量和函数,其作用域为当前cpp文件,其它的cpp文件不能访问该变量和函数。如果有两个cpp文件声明了同名的全局静态变量,那么他们实际上是独立的两个变量。

  static函数的好处是不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。头文件中的static变量如果在一个头文件中声明:

      static int g_vaule = 0;      

  那么会为每个包含该头文件的cpp都创建一个全局变量,但他们都是独立的,因为只是创建了一组同名而不同作用域的变量。但是也不建议这样的写法,因为不明确需要怎样使用这个变量。

  3、数据唯一性

  这是C++中static关键字的重用。主要指静态数据成员/成员函数。表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是“属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针. )

  static数据成员的初始化:(1) 初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。(2) 初始化时不加该成员的访问权限控制符private,public等。(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。(4) 静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。Static成员函数静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态的成员函数,这是由于静态的成员函数没有this指针。

原文链接: https://www.cnblogs.com/wangbenli/archive/2010/10/04/1841788.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    static用法

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/15724

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午3:45
下一篇 2023年2月7日 下午3:49

相关推荐