在C中static关键字有两层意思:隐藏性和持续性。在一个文件中定义的static变量只能在当前文件中使用;由static定义的局部变量存在于程序的整个生命周期(static的本地变量就是全局变量)。在C++的类中,对于一个成员来说,隐藏性可以由private、protected关键字实现,而成员的持续性依然由static关键字实现,独立于各个对象,不随着对象的不同而不同。static可以作用于类的成员变量以及函数,下面分别总结两者使用时的注意事项。
1.静态成员变量
使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。静态数据成员在定义时前面加关键字static,初始化时在类之外初始化,格式为:
<数据类型><类名>::<静态数据成员名>=<值> //静态变量的初始化
写在class内的东西都是声明而不是定义,因此对于静态成员需要在类外面给出其定义。静态成员在初始化时不能加static关键字,因为加了static关键字表明该变量只在当前文件内访问,而类设计时类中的成员变量是可能在其他文件中被访问的,两者相悖,因此这里不能加static关键字!
当静态成员为public时对其的访问可用对象名加.符号进行访问,也可以用类名加::作用域解析运算符进行访问。
在类的构造函数中对类的静态成员赋值时不能写成初始化列表的形式,因为静态成员只能在其定义的地方初始化,即类外,也可以只定义不做初始化。
2.静态函数
静态函数可以访问类的静态成员变量,且只能访问静态成员变量。调用时可以使用对象名加.符号进行调用,也可以使用类名加::作用于解析运算符进行调用。因此静态函数中不能使用this指针访问静态成员,因为当使用::进行调用静态函数时,此时是没有对象的,因此没有this指针!
示例:
#include <iostream>
using namespace std;
class A {
public:
A() { i = 0; }
void print() { cout << i << endl; }
void set(int ii) { i = ii; }
static void say(int ii) { cout << ii << ' ' << i << endl; }
//private:
static int i; // 全局的,所有对象共享这一个
};
int A::i; //静态成员的定义
int main() {
A a, b;
a.print();
a.set(10);
b.print();
b.set(5);
a.print();
// 若i为private,则以下两句都是不合法的!
cout << a.i << endl;
cout << A::i << endl;
a.say(10);
A::say(11);
return 0;
}
程序输出为:
0
10
5
5
5
10 5
11 5