c++中的static详解

1.静态局部变量

局部变量的生存期长于该函数。

  1. int f()
  2. {
  3. static int i = 1; // note:1
  4. //int i = 1; // note:2
  5. i+=1;
  6. return i;
  7. }

2.静态全局变量/函数

只在本文件可见。

  1. static int i = 1; //note:3
  2. //int i = 1; //note:4
  3. int foo()
  4. {
  5. i += 1;
  6. return i;
  7. }

对应extern关键字:

  1. //【file a.c】
  2. //static int n = 15; //note:5
  3. int n = 15; //note:6
  4. //【file b.c】
  5. #include <stdio.h>
  6. extern int n;
  7. void fn()
  8. {
  9. n++;
  10. printf("after: %d\n",n);
  11. }
  12. void main()
  13. {
  14. printf("before: %d\n",n);
  15. fn();
  16. }

我们先使用note:6,也就是非静态全局变量,发现输出为:
before: 15
after: 16
也就是我们的b.c通过extern使用了a.c定义的全局变量。
那么我们改成使用note:5,也就是使用静态全局变量呢?

  1. gcc a.c b.c -o output.out 1

会出现类似undeference to “n”的报错,它是找不到n的,因为static进行了文件隔离,你是没办法访问a.c定义的静态全局变量的,当然你用 #include “a.c”,那就不一样了。)。静态数据成员是每个class都有一份,普通数据成员是每个instance有一份,因此静态数据成员也叫作类变量,而普通数据成员也叫作实例变量

3.静态类变量

用于修饰class的数据成员,即所谓的静态成员,这种数据成员的生存期大于class的对象(实体instance)。
静态数据成员是每个class只有一份,普通数据成员是每个class有一份,普通数据成员是每个instance有一份,因此静态数据成员也叫作类变量,而普通数据成员也叫作实例变量

  1. #include<iostream>
  2. using namespace std;
  3. class Rectangle
  4. {
  5. private:
  6. int m_w,m_h;
  7. static int s_sum;
  8. public:
  9. Rectangle(int w,int h)
  10. {
  11. this->m_w = w;
  12. this->m_h = h;
  13. s_sum += (this->m_w * this->m_h);
  14. }
  15. void GetSum()
  16. {
  17. cout<<"sum = "<<s_sum<<endl;
  18. }
  19. };
  20. int Rectangle::s_sum = 0; //初始化
  21. int main()
  22. {
  23. cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;
  24. Rectangle *rect1 = new Rectangle(3,4);
  25. rect1->GetSum();
  26. cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;
  27. Rectangle rect2(2,3);
  28. rect2.GetSum();
  29. cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;
  30. system("pause");
  31. return 0;
  32. }

image.png
由图可知:

  • static 并不占用Rectangle的内存空间,而是在全局数据区(静态区)。
  • static只会被初始化一次,与实例无关。

    4.静态类函数

    用于修饰class的成员函数。

  • 静态成员函数不能访问非静态(包括成员函数和数据成员),但是非静态可以访问静态。

  • 调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以使用类名::函数名调用(因为他本身属于类,用类名调用很正常) ```cpp

    include

    using namespace std;

class Rectangle { private: int m_w,m_h; static int s_sum;

public: Rectangle(int w,int h) { this->m_w = w; this->m_h = h; s_sum += (this->m_w * this->m_h); }

  1. static void GetSum() //这里加上static
  2. {
  3. cout<<"sum = "<<s_sum<<endl;
  4. }

};

int Rectangle::s_sum = 0; //初始化

int main() { cout<<”sizeof(Rectangle)=”<GetSum(); cout<<”sizeof(rect1)=”<<sizeof(*rect1)<<endl; Rectangle rect2(2,3); rect2.GetSum(); //可以用对象名.函数名访问 cout<<”sizeof(rect2)=”<<sizeof(rect2)<<endl; Rectangle::GetSum(); //也可以可以用类名::函数名访问

  1. system("pause");
  2. return 0;

}

```