静态成员的提出是为了解决数据共享的问题。实现共享有许多方法,如:设置全局性的变量或对象是一种方法。但是,全局变量或对象是有局限性的。这一章里,我们主要讲述类的静态成员来实现数据的共享。
使用static成员而不是全局对象有三个优点:
1 static成员的名字在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突;
2 可以实现封装,static成员可以是私有的,而全局对象则不可以;
3 static成员 是与特定类关联的,并不与类的对象关联。
静态数据成员
在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。
使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。
静态数据成员的使用方法和注意事项如下:
1、静态数据成员在定义或说明时前面加关键字static。
2、静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下:
<数据类型><类名>::<静态数据成员名>=<值>
这表明:
(1) 初始化只能在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆,且只能初始化一次;
(2) 初始化时不加该成员的访问权限控制符private,public等。
(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
(4) static数据成员的类型可以是所属类的类型,还可以用作所属类的成员函数的默认实参;而非static数据成员可以被限定为所属类对象的引用或者指针,且不能用作默认实参。
3、静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。
4、引用静态数据成员时,采用如下格式:
<类名>::<静态成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。
下面举一例子,说明静态数据成员的应用:
从输出结果可以看到Sum的值对M对象和对N对象都是相等的。这是因为在初始化M对象时,将M对象的三个int型数据成员的值求和后赋给了Sum,于是Sum保存了该值。在初始化N对象时,对将N对象的三个int型数据成员的值求和后又加到Sum已有的值上,于是Sum将保存另后的值。所以,不论是通过对象M还是通过对象N来引用的值都是一样的,即为54。
特殊的const static数据成员:
只要初始化式是一个常量表达式, 整型const static数据成员就可以在类的定义体内进行初始化,C++primer注释说该数据成员仍必须在类外进行定义,而不必指定初始值;但实际在VS2008中运行时是不必要在类定义体外进行定义的。
class account
{
pubilc:
static double rate();
//........
private:
static const int period=30;
//........
};
const int account::period; //定义可要可不要,但不必再次指定初始值
静态成员函数:
静态成员函数可以类内或类外定义,但必须在类内声明;
static成员函数没有this指针,所以不能直接引用非static数据成员;
static成员不是任何对象的组成,所以static成员函数不能被声明为const,因为const只限定该类的对象;
static成员函数不能同时被声明为虚函数。
使用static成员而不是全局对象有三个优点:
1 static成员的名字在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突;
2 可以实现封装,static成员可以是私有的,而全局对象则不可以;
3 static成员 是与特定类关联的,并不与类的对象关联。
静态数据成员
在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。
使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。
静态数据成员的使用方法和注意事项如下:
1、静态数据成员在定义或说明时前面加关键字static。
2、静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下:
<数据类型><类名>::<静态数据成员名>=<值>
这表明:
(1) 初始化只能在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆,且只能初始化一次;
(2) 初始化时不加该成员的访问权限控制符private,public等。
(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
(4) static数据成员的类型可以是所属类的类型,还可以用作所属类的成员函数的默认实参;而非static数据成员可以被限定为所属类对象的引用或者指针,且不能用作默认实参。
3、静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。
4、引用静态数据成员时,采用如下格式:
<类名>::<静态成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。
下面举一例子,说明静态数据成员的应用:
#include class Myclass { public: Myclass(int a, int b, int c); void GetNumber(); void GetSum(); private: int A, B, C; static int Sum; }; int Myclass::Sum = 0; Myclass::Myclass(int a, int b, int c) { A = a; B = b; C = c; Sum += A+B+C; } void Myclass::GetNumber() { cout<<"Number="<<a<<","<<b<<","<<c<<endl; } void Myclass::GetSum() { cout<<"Sum="< } void main() { Myclass M(3, 7, 10),N(14, 9, 11); M.GetNumber(); N.GetNumber(); M.GetSum(); N.GetSum(); } </a<<","<<b<<","<<c<<endl; |
从输出结果可以看到Sum的值对M对象和对N对象都是相等的。这是因为在初始化M对象时,将M对象的三个int型数据成员的值求和后赋给了Sum,于是Sum保存了该值。在初始化N对象时,对将N对象的三个int型数据成员的值求和后又加到Sum已有的值上,于是Sum将保存另后的值。所以,不论是通过对象M还是通过对象N来引用的值都是一样的,即为54。
特殊的const static数据成员:
只要初始化式是一个常量表达式, 整型const static数据成员就可以在类的定义体内进行初始化,C++primer注释说该数据成员仍必须在类外进行定义,而不必指定初始值;但实际在VS2008中运行时是不必要在类定义体外进行定义的。
class account
{
pubilc:
static double rate();
//........
private:
static const int period=30;
//........
};
const int account::period; //定义可要可不要,但不必再次指定初始值
静态成员函数:
静态成员函数可以类内或类外定义,但必须在类内声明;
static成员函数没有this指针,所以不能直接引用非static数据成员;
static成员不是任何对象的组成,所以static成员函数不能被声明为const,因为const只限定该类的对象;
static成员函数不能同时被声明为虚函数。