myClock.showTime();//引用具有块作用域的对象
}
5.3类的静态成员P153
静态成员是解决同一个类的不同对象之间的数据和函数共享问题的。
例,抽象出某公司全体雇员的共性,设计如下的雇员类:
classEmployee{//雇员类
private :
intempNo ;
intid ;
stringname ;//字符串对象
...
}
若需要统计雇员总数,这个数据存放在什么地方呢?
若以类外的变量来存储总数,不能实现数据的隐藏。
若在类中增加一个数据成员用以存放总数,必然在每一个对象中都存储一个副本,不仅冗余,且每个对象分别维护一个“总数”,势必造成数据的不一致性。
比较理想的方案是类的所有对象共同拥有一个用于存放总数的数据成员。
5.3.1静态数据成员P154
实例属性
“一个类的所有对象具有相同的属性”,是指属性的个数、名称、数据类型相同,各个对象的属性值则可各不相同。
以类的非静态数据成员表示。
类属性
是描述类的所有对象的共同特征的一个数据项,对于任何对象实例,它的属性值是相同的。
通过静态数据成员来实现“类属性”。
静态数据成员的访问
静态数据成员不属于任何一个对象,只能通过类名对它访问,用法是“类名:
:
标识符”。
静态数据成员的说明和定义
在类的声明中仅仅对静态数据成员进行引用性说明,必须在文件作用域的某处用类名限定进行定义性说明,这时也可进行初始化。
在UML中,静态数据成员下方添加下划线。
例5-4具有静态数据成员的Point类。
引入静态数据成员的Point类。
图5-2包含静态数据成员的Point类的UML图
Point
–x:
int
–y:
int
–count:
int=0
+Point(xx:
int=0,yy:
int=0)
+getX():
int
+getY():
int
+Point(p:
Point&)
+showCount():
void
#include
usingnamespacestd;
classPoint//Point类定义
{
public:
Point(intxx=0,intyy=0):
x(xx),y(yy){count++;}//所有对象共同维护count
Point(Point&p){x=p.x;y=p.y;count++;}
~Point(){count--;}
intgetX(){returnx;}
intgetY(){returny;}
voidshowCount(){cout<<"对象count="<private:
intx,y;
staticintcount;//静态数据成员声明,用于记录点的个数
};
intPoint:
:
count=0;//静态数据成员定义和初始化,使用类名限定
voidmain()
{
Pointa(4,5);//定义对象a,其构造函数会使count增1
cout<<"Pointa:
"<a.showCount();//输出对象个数
Pointb(a);//定义对象b,其拷贝构造函数会使count增1
cout<<"Pointb:
"<b.showCount();
}
在对类的静态私有数据成员初始化的同时,还可引用类的其他私有成员。
例,若一个类T存在类型T的静态私有对象,则可引用该类的私有构造函数将其初始化。
5.3.2静态函数成员P156
静态成员函数是使用static关键字声明的函数成员。
静态成员函数属于整个类,由同一个类的所有对象共同维护,并共享。
对于公有的静态成员函数,可通过类名或对象名来调用。
静态成员函数可直接访问该类的静态数据和函数成员,而访问非静态数据成员,必须通过参数传递方式得到对象名,然后通过对象名来访问。
classA{
public:
staticvoidf(Aa);
private:
intx;
};
voidA:
:
f(Aa){
cout<可用A:
:
f(c)调用,此时,无当前对象。
cout<}
在UML中,静态函数成员前添加<>。
例5-5具有静态数据和函数成员的Point类。
图5-3包含静态函数成员的Point类的UML图
Point
–x:
int
–y:
int
–count:
int=0
+Point(xx:
int=0,yy:
int=0)
+getX():
int
+getY():
int
+Point(p:
Point&)
<>+showCount():
void
#include
usingnamespacestd;
classPoint{
public:
Point(intxx=0,intyy=0):
x(xx),y(yy){count++;};
Point(Point&p){x=p.x;y=p.y;count++;}
~Point(){count--;}
intgetX(){returnx;}
intgetY(){returny;}
staticvoidshowCount(){cout<<"对象count="<private:
intx,y;
staticintcount;//静态数据成员声明
};
intPoint:
:
count=0;//静态数据成员定义及初始化,使用类名限定
voidmain()
{
Pointa(4,5);
cout<<"Pointa:
"<Point:
:
showCount();//输出对象号,类名引用
Pointb(a);
cout<<"Pointb:
"<b.showCount();//输出对象号,对象名引用
}
采用静态函数成员的好处
可不依赖于任何对象,直接访问静态数据。
5.