首页 > 谁知道静态成员的纠结心境

谁知道静态成员的纠结心境

我们在实际开发的过程中,可能需要某些类的成员变量并不是针对每一个对象的,而是针对每一个类而言的,比如在银行中有一个利率数据,我们希望的是,当一个利率改变的时候,所有的对象都能够看到这个改变的数据,并利用它,而不是每一个对象都有一个利率成员变量。这个时候就设计到了静态成员变量。


一. 内存那些事
静态成员变量是存放在静态全局区(数据段),一个对象改变了其中的静态变量,其他对象的这一变量也都随之改变。
说其是静态变量,个人是这样理解的,该变量不会因为某一次函数调用或者某个对象的销毁而销毁,它是一直存在在静态全局区的。也可以这样理解,它在静态全局区的位置始终没有变过,它是静止不动的,直到整个程序结束掉。


二. C语言中"自私"的static(他人不可见)
static的三个私生子
说static三个私生子,个人的理解是这个样子的,static修饰的变量或者是函数只在当前文件中有用,其他的文件对这些函数或者是变量都是不可见的。
私生子承受了这么大的压力,当然是要给与好处的,对于静态变量如果没有初始化的话,如果这个变量是int类型的,它被初始化为0,如果是字符型的,则被初始化为''。


私生子1--局部变量(私生子中的私生子)
修饰局部变量的时候虽然它的存储方式发生了改变,由原来的栈区放置在了静态全局区,这个时候,他是一直存在着的,但是它的作用域没有改变,就是说它依然在只这个函数里面有效。


私生子1--全局变量
如果是一个普通的全局变量,比如在一个工程中的某个文件中定义的变量在其他的文件中也可以使用,此时只需要加上一个extern就可以使用了,但是这个全局变量加上static之后就不能在其他的文件中使用了。它在其他文件中的可见性就改变了
私生子3--函数
修饰函数的时候和修饰变量的情况差不多,只不过是改变了函数的可见性而已


三. C++中“孤独”的static(没有“对象”的对象)
当我们在类中定义一个静态变量的时候,实际上是声明一个静态变量,拥有静态变量的每个类创建的对象中实际是没有这个静态成员变量的相关的数据的,这个成员变量是存放在静态全局区,所以我们要在类的外面声明这个静态变量在类外定义的时候,要加上类的作用域符号,指定是哪个类的静态成员。
因为静态成员变量不属于任何一个对象,所以我们不能使用类的构造函数进行静态成员变量的初始化,我们必须在类的外部定义并初始化静态成员变量
静态成员函数是没有this指针的,同样的道理,静态函数在只有一个副本,它不属于任何一个对象所拥有。


调用静态成员函数的几种方式
static修饰的变量或者函数只有一个副本,它不属于任何一个对象的,所以这个可以使用对象和类去访问,用类访问的时候需要加上类的作用域
虽然静态成员函数不属于某个对象,使用类的对象、引用和指针来进行访问,还有一种方式是使用类名::函数名进行访问(原因是这个函数也是静态的)。


四. static的死对头--extern
关于extern,我们可以使用extern在一个文件中去访问其他文件中的函数或者是变量,但是这个时候要求如果访问的是变量的话,则要求访问的变量是全局属性的,并且不是静态的,如果这个变量是在一个函数内部的,即是时在main函数的内部也访问不了,因为它不具有全局属性。
我们为什么不使用#include这种方式来调用函数或者是一个变量呢,因为是extern的速度更快
还应该注意的一个问题是,我们经常说的是数组名实际上是一个指针,就是在使用的时候完全可以把它当做一个指针来使用,但是如果我们在一个文件中定义了一个全局数组,比如char arr[] = "hello";然后在另一个 变量中 去使用extern char* arr;,但是这个时候是错误的,因为数组和指针还是有不同 的,这个时候只有声明为extern char arr[];才可以使用。
五. static的好基友--全局变量
总结:其实静态变量和全局变量有很多地方一样,唯一的不同时静态全局变量具有隐藏的属性。




看看静态成员可以帮我们解决什么问题吧
求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句


    #include   using namespace std;  class Temp  {  public:  Temp()  {  ++N;  Sum+=N;  }  static void Reset()  {  N=0;  Sum=0;  }  static int GetSum()  {  return Sum;  }  private:  static int N;  static int Sum;  };  int Temp::N=0;  int Temp::Sum=0;  int solution_Sum(int n)  {  Temp::Reset();  Temp *a=new Temp[n];  delete []a;  a=0;  return Temp::GetSum();  }  int main()  {  cout<






解题思路:因为定义了静态成员变量,我们这里定义了对象数组,每次实例化一个对象 的时候,就会改变静态变量,而且是累加的,所以到最后就得到了结果了。














































更多相关:

  • 多线程编程 mind-Mapping保存有一下导图的xmind文件,可直接获取 互斥变量 互斥对象 ptrhead相关接口 条件变量 future异步访问类 async类 promise类 package_task类...

  • volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。在DSP开发中,经常需要等待某个事件的触...

  •   引子     阅读以下代码,并尝试分析 代码解析 在主线程中,线程Id为1,为线程变量赋值 变量==d6ff开启一个新的task,此时线程Id为4,变量==d6ff,并调用Task1开启一个同步Task3,线程Id为1。变量==d6ff,修改值==f598此时第二步启动的Task1运行,线程Id为4,变量==d6ff,修改值=...

  • 操作系统基础    操作系统是协调、控制、管理计算机硬件资源与软件资源的控制程序 为什么要用操作系统?    1.操作系统可以把复杂的操作简化给用户使用或者应用程序  2.可以让应用程序对计算机硬件竞争变的有序  一套完整的计算机分为:操作系统、应用程序、计算机硬件 编程语言的分类   机械语言:使用二进制让计算机工作   优点:运行...

  • 针对高并发量的处理 一个老生常谈的话题了 至于需要运维支持的那些cdn、负载均衡神马的就不赘述了 你们都懂的 虫子在此博文只讲一些从程序角度出发的一些不错的解决方案。 至于从数据库角度的性能方案、虫子另开博文。 1. 首推静态化 推荐指数五颗星 满星五颗 只要是大型互联网应用基本上离不开这个概念,IIS自带的伪静态化不谈,但是想做好...

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...