静态数据成员
1.静态数据成员的定义。
静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。 其定义方式与全局变量相同。
2.在函数体内静态变量具有“记忆”功能,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变。
与全局变量相比,使用静态数据成员的优势:
静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。(静态数据成员属于本类的所有对象共享)。
可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能。
3.静态数据成员被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下:
1 class base{ 2 public : 3 static int _num;//声明 4 }; 5 int base::_num=0;//静态数据成员的真正定义 6 7 class derived:public base{ 8 }; 9 10 main() 11 { 12 base a; 13 derived b; 14 a._num++; 15 cout<<"base class static data number _num is"<<a._num<<endl; 16 b._num++; 17 cout<<"derived class static data number _num is"<<b._num<<endl; 18 }
// 结果为1,2;可见派生类与基类共用一个静态数据成员。
4.静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。举例如下:
class base{ public : static int _staticVar; int _var; void foo1(int i=_staticVar);//正确,_staticVar为静态数据成员 void foo2(int i=_var);//错误,_var为普通数据成员 };
5.★静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用。举例如下:
class base{ public : static base _object1;//正确,静态数据成员 base _object2;//错误 base *pObject;//正确,指针 base &mObject;//正确,引用 };
6.★静态数据成员的值在const成员函数中可以被合法的改变。举例如下:
1 class base{ 2 public: 3 base(){_i=0;_val=0;} 4 5 mutable int _i; //类数据成员加上mutable后,修饰为const的成员函数就可以修改它 6 static int _staticVal; 7 int _val; 8 void test() const{//const 成员函数 9 10 _i++;//正确,mutable数据成员 11 _staticVal++;//正确,static数据成员 12 _val++;//错误 13 } 14 };
静态成员函数:
1.静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态的成员函数,这是因为静态成员函数不含this指针。
2.静态成员函数是类的成员函数,该函数不属于该类申请的任何一个对象,而是所有该类成员共同共有的一个函数。
为什么static变量只初始化一次?
对于所有对象(不仅仅是静态对象),初始化都只有一次,而由于静态变量具有“记忆”功能,初始化后一直没有被销毁,都会保存在内存区域汇总,所以不会再次初始化。