(一)在C语言中
静态变量永远只能初始化一次(运行时),但是可以多次赋值,
静态变量的内存地址在编译后就确定了。
(1)局部静态变量,存在于全局数据区
example1:
#include <stdio.h>
int function()
{
static int a = 10;
<span style="white-space:pre"> </span>a++;
return a;
}
int main()
{
for(int nIndex = 0;nIndex<10;nIndex++)
{
printf("a = %d\n",function());
}
}
输出结果为11,12,13,14,15,16,17,18,19,20
红色为定义,只定义一次。实现机制:为a记录一个是否初始化的状态,看看汇编就知道了。
example2:
#include <stdio.h>
int function()
{
static int a;
a = 0;
a++;
return a;
}
int main()
{
for(int nIndex = 0;nIndex<10;nIndex++)
{
printf("a = %d\n",function());
}
}
输出结果为:1,1,1,1,1,1,1,1,1,1
红色同样为定义;但绿色为赋值不是定义。
(2)全局静态变量:存在于全局数据区
全局静态变量具有文件属性,只属于定义它的编译单元。
example1:
//a.cpp
static int AAA = 10;
//b.cpp
static int AAA = 20;
不会有链接错误,但如果把static去掉那便有链接错误了
(3)全局静态函数:
具有文件属性,全局变量同
(二)在C++中
(1)同C部分略
(2)static成员变量:有时需要全局对象,但全局对象破坏封装,而且容易发生冲突。所以用static成员变量。
a. static成员变量在使用前如果没有初始化,那么会有链接错误:
//test.h
#ifndef _TEST_H_
#define _TEST_H_
class CTest
{
public:
CTest(){;}
~CTest(){;}
static int GetAAA(){return AAA;}
public:
static int AAA;
};
#endif
//main.cpp
#include "test.h"
#include <iostream>
using namespace std;
int main()
{
CTest* pTest = new CTest();
int a = 0;
a = CTest::GetAAA();
a = pTest->AAA;//因为AAA是public,private则编译错误
a = CTest::AAA;//因为AAA是public,private则编译错误
int b;
cin>>b;
return 0;
}
链接错误。需要对静态成员变量进行初始化,初始化方式与static const成员变量相同:#ifndef _TEST_H_
#define _TEST_H_
class CTest
{
public:
CTest(){;}
~CTest(){;}
static int GetAAA(){return AAA;}
public:
static int AAA;
};
int CTest::AAA = 10;
#endif
b.static数据成员可以是该成员所述的类类型。非static成员被限定声明为其自身类对象的指针和引用。
class CTest;
class CTest
{
public:
Ctest(){}
~CTest(){}
public:
static CTest test1;//ok
CTest* test2;//ok
CTest test3;//ok
}
c.static数据成员可用作默认实参:#ifndef _TEST_H_
#define _TEST_H_
class CTest
{
public:
CTest(){;}
~CTest(){;}
static int GetAAA(){return AAA;}
void SetA(int para = AAA)//ok,注意必须对AAA先进行初始化
{
a = para;
}
public:
int a;
static int AAA;
};
int CTest::AAA = 10;
#endif
(3)静态成员函数a.静态成员函数没有this形参,也就说没法操作具体对象,所以静态成员函数只能操作不属于任何对象的static成员变量。
b.静态成员函数不能被声明为const。因为const是由指向const对象的const指针来实现的,but you know静态成员函数是不能操作具体对象的,因为它没有this指针作为其形参。
c.静态成员函数不能被声明为虚函数。虚函数存在的意义就是运行时多态,实现的机制是根据不同的对象调用不同的成员方法,静态成员声明为虚函数没意义。