1. static关键字的使用形式:
static可以用作函数和变量的前缀,用以修饰变量,函数,数据成员,成员函数。
(1)在C/C++中,修饰变量或函数:如,static int a; // 静态变量
static get_a(){ return a;} // 静态函数
(2)在C++中,修饰数据成员或者成员函数:如,
class A {
private:
static int a; // 静态数据成员
public:
static int get_a(void); // 静态成员函数
};
2. static关键字的功能:
(1)对于函数来讲,static的作用仅限于隐藏
(2)对于变量,除了隐藏,static还有下面两个作用:保持变量内容的持久;默认初始化为0。
3. 静态变量的特点:
(1)静态局部变量在定义它的函数内部时可见的,只能被定义它的函数使用。
(2)静态变量存放在内存的静态数据区,静态局部变量一经定义不会再次分配存储空间,也不会自行消失,直到程序运行结束,这一点与全局变量相同。
(3)静态变量默认初始值为0,也可专门初始化,这一点又与全局变量相同。
(4)存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量
4. 静态函数访问规则:
(1)在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其它函数访问;
(2)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(3)对于静态变量和非静态变量,只要其对于函数是可见的,那么,无论函数前面是否有static,均可以访问该变量。
例:
/* 编辑编译环境:Dev-C++ 4.9.9.2 */
/* file1: staticDefine.h */
#include <stdio.h>
#include <stdlib.h>
static int staticValue;
static void printValue()
{
staticValue++;
printf(" staticValue = %d /n", staticValue);
}
/* file2: staticTest.cpp */
#include "staticDefine.h"
typedef struct
{
bool Hwd_Audio_MainMic_Open;
bool HWwd_Audio_HeadsetMic_Open;
int *TestP;
}HwdAudioAutoTest;
static HwdAudioAutoTest CitAudioAutoTest;
int main()
{ // result:
printf("%d /n", staticValue); // 0
printValue(); // 1
printf("%d, %d, %d/n", CitAudioAutoTest.Hwd_Audio_MainMic_Open, CitAudioAutoTest.Hwd_Audio_MainMic_Open, CitAudioAutoTest.TestP); // 0 0 0
{
static int x = 12;
printf("x = %d /n",x); //12
}
//printf("x = %d /n",x); //error
while(1);
}
5. 静态数据成员的特点(见例1):
(1)除了在类定义中列出静态类成员外,还必须在源文件中为其分配空间,可以同时进行显示初始化,如果不进行显示初始化,则默认初始化为0;
(2)静态数据成员可以被类中的任何成员函数访问.
例1:
// 例1:
/* 编辑编译环境:Dev-C++ 4.9.9.2 */
#include <stdio.h>
class A {
private:
static int a;
//static int b = 0; //error: ISO C++ forbids in-class initialization of non-const static member `b'
//请与static const int b = 0; 作比较
public:
static int get_a(); // 静态成员变量a 可以被静态成员访问
int get_a2()
{
return a; // 静态成员变量a可以被非静态成员访问
};
};
int A::a; //必须为静态数据成员分配空间,否则,会出现如下link error: undefined reference to `A::a'。这里,采用自动初始化为0,等价于 int A::a = 0;
int A::get_a()
{
return a;
}
int main(void)
{
A a1;
printf("A::get_a(): %d /n",A::get_a()); // 0, get_a只能通过类来调用
printf("a1.get_a2(): %d ",a1.get_a2()); //0, get_a2只能通过对象来调用.
while(1);
}
代码说明:
错误1: ISO C++ forbids in-class initialization of non-const static member `b'
解释:int型的静态数据成员有默认值,且是0,在定义时不可以进行赋值操作。
6. 静态成员函数的特点(见例2):
(1) 静态成员函数只可以引用本类的静态数据成员或其它(外部函数,其它类)的静态成员函数,因为这些成员在没有建立对象之前就已经存在,无须引用一个类实例便可以被调用;
(2)同时,静态成员函数无法直接访问未经实例化的非静态成员,因为静态成员函数没有指定存放对象的地址。
静态成员函数要想访问该对象的非静态成员,只能通过对象名或指向对象的指针来访问。
例2:
/* 编辑编译环境:Dev-C++ 4.9.9.2 */
// 例2:
#include <stdio.h>
static int ver = 10;
static int get_ver(void) { return ver; }
class B {
private:
static int b;
public:
static int get_b();
int get_b2()
{
return b;
};
};
int B::b;
int B::get_b()
{
return b;
}
class C {
private:
int i;
static int j;
public:
static void getFun(void)
{
//i++; //error, 参考第一条说明, 静态成员函数不能访问本类的非静态数据成员。
//B::get_b2(); //error, 参考第二条说明, 静态成员函数不能访问未经实例化的非静态成员。
j++; //OK, 参考第一条说明,getFun可以引用本类的静态数据成员
get_ver(); //OK,参考第一条, getFun可以引用外部函数的静态成员函数
B::get_b(); //OK,参考第一条, getFun可以其它类的静态成员函数
B b1;
b1.get_b2(); //OK, 参考第二条说明, 静态成员函数可以访问已经实例化的非静态成员。
}
static int get_i( C &x)
{
return x.i; //OK,// 静态成员函数通过对象名来访问该对象的非静态成员
}
};
int C::j = 0; // 必须进行初始化
int main(void)
{
C c1;
printf("x = %d /n", C::get_i(c1));
C::getFun();
while(1);
}