1.静态局部变量
局部变量的生存期长于该函数。
int f()
{
static int i = 1; // note:1
//int i = 1; // note:2
i+=1;
return i;
}
2.静态全局变量/函数
只在本文件可见。
static int i = 1; //note:3
//int i = 1; //note:4
int foo()
{
i += 1;
return i;
}
对应extern关键字:
//【file a.c】
//static int n = 15; //note:5
int n = 15; //note:6
//【file b.c】
#include <stdio.h>
extern int n;
void fn()
{
n++;
printf("after: %d\n",n);
}
void main()
{
printf("before: %d\n",n);
fn();
}
我们先使用note:6,也就是非静态全局变量,发现输出为:
before: 15
after: 16
也就是我们的b.c通过extern使用了a.c定义的全局变量。
那么我们改成使用note:5,也就是使用静态全局变量呢?
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有一份,因此静态数据成员也叫作类变量,而普通数据成员也叫作实例变量。
#include<iostream>
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);
}
void GetSum()
{
cout<<"sum = "<<s_sum<<endl;
}
};
int Rectangle::s_sum = 0; //初始化
int main()
{
cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;
Rectangle *rect1 = new Rectangle(3,4);
rect1->GetSum();
cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;
Rectangle rect2(2,3);
rect2.GetSum();
cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;
system("pause");
return 0;
}
由图可知:
- static 并不占用Rectangle的内存空间,而是在全局数据区(静态区)。
-
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); }
static void GetSum() //这里加上static
{
cout<<"sum = "<<s_sum<<endl;
}
};
int Rectangle::s_sum = 0; //初始化
int main()
{
cout<<”sizeof(Rectangle)=”<
system("pause");
return 0;
}
```