我们在实际开发的过程中,可能需要某些类的成员变量并不是针对每一个对象的,而是针对每一个类而言的,比如在银行中有一个利率数据,我们希望的是,当一个利率改变的时候,所有的对象都能够看到这个改变的数据,并利用它,而不是每一个对象都有一个利率成员变量。这个时候就设计到了静态成员变量。
一. 内存那些事
静态成员变量是存放在静态全局区(数据段),一个对象改变了其中的静态变量,其他对象的这一变量也都随之改变。
说其是静态变量,个人是这样理解的,该变量不会因为某一次函数调用或者某个对象的销毁而销毁,它是一直存在在静态全局区的。也可以这样理解,它在静态全局区的位置始终没有变过,它是静止不动的,直到整个程序结束掉。
二. C语言中"自私"的static(他人不可见)
static的三个私生子
说static三个私生子,个人的理解是这个样子的,static修饰的变量或者是函数只在当前文件中有用,其他的文件对这些函数或者是变量都是不可见的。
私生子承受了这么大的压力,当然是要给与好处的,对于静态变量如果没有初始化的话,如果这个变量是int类型的,它被初始化为0,如果是字符型的,则被初始化为'\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 <iostream>  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<<solution_Sum(100)<<endl;  return 0;  }  
解题思路:因为定义了静态成员变量,我们这里定义了对象数组,每次实例化一个对象 的时候,就会改变静态变量,而且是累加的,所以到最后就得到了结果了。

谁知道静态成员的纠结心境相关推荐

  1. CPPDay05 C的静态成员,类的静态成员,单例模式,静态成员函数,继承(面向对象三大特性,高类聚,低耦合),继承方式(private,protected,public)多重复杂继承,虚继承

    目录 0x00 C中的静态成员: 0x01类的静态成员: 0x02单例模式: 0x03静态成员函数: 0x04继承: 0x05继承方式: 0x06多重复杂继承: 0x07虚继承: 0x00 C中的静态 ...

  2. 不要纠结于过去发生的事

    在这个社会中,有些人很早就经历了一些不好的事,遇到不好的人:让他留了一些阴影.这时,应该学会不要纠结于过去发生的事情了!一件事情已经发生了,不管再怎么后悔也不能改变结局: 对这件事一直有懊悔之心,只会 ...

  3. 为什么静态方法无法直接调用非静态成员变量和方法

    静态方法无法直接调用非静态成员变量和方法 看到这句话,要想到形容的是这样的如下 静态方法里面无法调用非静态变量 下面在写一个对比非静态的方法和静态方法调用变量对比 问题原因 静态变量和静态的方法是属于 ...

  4. C++ 笔记(18)— 类和对象(this 指针、指向类的指针、类静态成员变量和函数)

    1. this 指针 在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址. this 指针是所有成员函数的隐含参数.因此,在成员函数内部,它可以用来指向调用对象. 友元函数没有 thi ...

  5. c++静态成员函数好处

    静态成员函数主要为了调用方便,不需要生成对象就能调用. 比如: class X { public:void MethodA();static void MethodB(); } 此时MethodB可以 ...

  6. 【C#小知识】C#中一些易混淆概念总结(三)---------结构,GC,静态成员,静态类...

    目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) ---------------------------------------分割线----------- ...

  7. 友元函数、类的非静态成员函数、静态成员函数的区别

    类中申明的函数相对于类来说有三层意思: 1.有this指针 2.函数在类的作用区域中 3.可以访问类中私有部分 4.可以被继承 非静态成员函数具有1234 静态成员函数具有234 友元函数具有3 静态 ...

  8. C++类的静态成员详细讲解

    在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...

  9. php面向对象静态常量,浅谈PHP面向对象编程(四、类常量和静态成员)

    4.0 类常量和静态成员 通过上几篇博客我们了解到,类在实例化对象时,该对象中的成员只被当前对象所有.如果希望在类中定义的成员被所有实例共享. 此时可以使用类常量或静态成员来实现,接下来将针对类常量和 ...

最新文章

  1. nginx conf 文件配置
  2. [转]深入理解G1垃圾收集器
  3. c#下如何生成安装程序
  4. python df head_在方法()中调用时,Pandas Df.head()不显示?
  5. 绝地求生更新完后显示服务器忙,绝地求生2月1日更新好了吗?更新后提示服务器繁忙怎么办?...
  6. 深度学习自学(十六):caffe-sphereface识别代码编译问题-caffe sudo make test报错
  7. IE8_XP安装包.zip
  8. BT656跟BT1120和BT709有什么区别
  9. 超级搜索术2-人脉搜索/分类整理
  10. Python批量移动文件到指定目录
  11. 非线性控制1.0——自适应控制和鲁棒控制
  12. ps怎么做玻璃破碎碎片飞溅效果
  13. 清北学堂济南刷题班day1
  14. background详解
  15. 如何使用Python api 函数写股票策略
  16. c++ 11 多线程支持 (std::packaged_task)
  17. ppt输出图片更改分辨率设置
  18. 蓝桥杯 青少年创意编程大赛 scratch组 (二)
  19. vba传值调用_VBA传递参数步骤
  20. CIMPLICITY标签导入导出功能简单介绍

热门文章

  1. 用C#钩子写一个改键外挂
  2. CodeForces Round #287 Div.2
  3. MySQL性能测试工具 mysqlslap
  4. 二叉树的前序,中序,后序的递归、迭代实现
  5. usaco Riding the Fences(欧拉回路模板)
  6. usaco wormhole(看了官方视频题解)
  7. python nltk book_NLTK学习笔记(一):语言处理和Python
  8. centos6卸载mysql服务器_CentOS6.5下卸载自带的MySQL数据库安装MySQL5.6
  9. c语言一行黑白相间的瓷砖,C语言编程练习15:贴瓷砖
  10. linux重启sh脚本,Linux 之shell脚本系列之服务启动/关闭/重启/状态