C++的类中,可以使用静态成员变量和静态成员函数。用法与普通成员变量与普通成员函数有较大区别,故总结如下。
static成员函数与非static成员函数的区别
在C++类和对象的概念中,先有类,才有对象。因此static成员函数和static成员变量是在类产生的时候分配的内存,产生于对象之前,故不能在static成员函数中调用普通的成员变量和成员函数。而且在static成员函数后面不能加const。
调用方法不同
非static成员通过对象调用
static成员通过作用域操作符直接调用,或者通过对象、引用、指向该类类型对象的指针间接调用
1
2
3
4
5
6
7
8
9
10class Lunais{
static double zty();
double zzz;
};
Lunais z;
Lunais *t = &z;
double zty;
zty = Lunais::zty(); //static成员通过作用域操作符直接调用
zty = z.zty(); //static成员通过对象间接调用
zty = t->zty(); //static成员通过指向该类类型对象的指针间接调用访问成员不同
- 类的非static成员函数是可以直接访问类的static和非static成员,而不用作用域操作符
- static成员函数没有this形参,它可以直接访问所属类的static成员,但不能直接使用非static成员
定义方式不同
一般情况下,static数据成员是类内声明,类外定义
static成员不通过类构造函数初始化,而是在定义时进行初始化
(构造函数是对类的对象进行初始化,因此static成员和构造函数没有什么关系)
const static数据成员在类的定义体中出始化时,该数据成员仍必须在类的定义体外定义,只是不再指定初始值
1
2
3
4
5
6
7
8
9
10
11
12class circle {
int a; // 普通变量,不能在类中初始化
static int b; // 静态变量,不能在类中初始化
static const int c=2; // 静态常整型变量,可以在类中初始化
static const double PI=3.1416; //error C2864:
//只有静态常量整型数据成员才可以在类中初始化
} ;
const int cicle::c ;
//const static数据成员在类的定义体中初始化时,该数据成员仍必须在类的定义体外定义,只是不再指定初始值
int circle::b = 2; //b可以在类外进行初始化,且所有对象共享一个b的值;
static成员的名字在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突
关于staic成员函数和static成员变量一个完整的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51class Tank {
public:
Tank(char code);
~Tank();
void fire();
static int getCount();//这就是静态成员函数
//static int getCount() const;
//这种在static后面加const的行为是非法的,因为加const的本质是在给this指针加一个const,但static型成员函数的里没有this指针,因为其是依托于类的,不是依托于对象的,this本质就是对象,这里不需要对象,所以没有this指针
private:
char m_cCode;//坦克编号
static int s_iCount;//用静态变量来计数
};
int Tank::s_iCount = 0;
//这里是对类里面静态成员变量的初始化。
//要特别注意,static型变量不能在构造函数中初始化,而且不用加static关键字了
Tank::Tank(char code) {
m_cCode = code;
s_iCount++;
cout << "tank" << endl;
}
Tank::~Tank() {
s_iCount--;
cout << "~Tank" << endl;
}
void Tank::fire() {
cout << "Tank--fire" << endl;
}
//这里就是static型函数的初始化
//注意这里不加static关键字
//而且注意,在static函数中不能调用普通的成员变量和普通的成员函数
int Tank::getCount() {
return s_iCount;
}
int main() {
cout<<Tank::getCount()<<endl;
//这里注意,static函数和变量是在类编译时候就产生,不是依托于对象产生的
Tank* p = new Tank('A');//堆上分配内存
cout << p->getCount() << endl; ////static成员通过指向该类类型对象的指针间接调用
system("pause");
return 0;
}