静态成员 :在定义前面加了static关键字的成员
例如:
class CRectangle{
private:
int w, h;
static int nTotaArea; // 静态成员变量
static int nTotalNumber;
public:
CRectangle(int w_, int h_);
~CRectangle();
static void PrintTotal(); // 静态成员函数
}
普通成员变量每个对象各自一份, 静态成员变量一共就一份, 为所有对象共享
class CMyclass{
int n;
static int s;
};
sizeof (CMYclass) 等于 4
- 普通成员变量对每个对象各自一份, 而静态成员变量一共就一份
- 普通成员函数必须作用于某个对象,而静态成员函数并不作用于某个对象
- 因此静态成员可以不需要对象而进行访问
如何访问静态成员
- 类名::成员名
CRectangle::PrintTotal(); - 对象名.成员名
CRectangle r;
r.PrintTotal(); - 指针->成员名
CRectangle *p = &r;
p->PrintTotal(); - 引用.成员名
CRectangle & ref = r;
int n = ref.nTotalNumber;
注意:
- 静态成员变量本质上是全局变量, 哪怕一个对象都不存在,类的静态成员变量也存在
- 静态成员函数本质上是全局函数
- 设置静态成员这种机制的目的都是和某些类关联起来,看起来更像是一个整体,易于维护
静态成员示例
设置一个矩阵类,利用全局变量记录总数和总面积
class CRectangle{
private:
int w, h;
static int nTotalArea;
static int nTotalNumber;
public:
CRectangle(int w_, int h_);
~CRectangle();
static void PrintTotal();
};
CRectangle::CRectangle(int w_, int h_){
w = w_;
h = h_;
nTotalNumber ++;
nTotalArea += w*h;
}
CRectangle :: ~CRectangle(){
nTotalNumber --;
ntotalArea -= w*h;
}
void CRectangle::PrintTotal(){
cout << nTotalNumber << "," << nTotalArea << endl;
}
int CRectangle::nTotalNumber = 0;
int CRectangle::nToalArea = 0;
// 必须提前对类中的静态成员进行初始化
int main(){
CRectangle r1(3, 3), r2(2, 2);
// cout << CRectangle::nTotalNumber; // wrong, 私有
CRectangle::PrintTotal();
return 0;
}
上述代码的缺陷
在使用CRectangle类时, 有时会调用复制构造函数生成临时隐藏的CRectangle对象, 临时对象在消亡时会调用析构函数,减少nTotalNumber 和 nTotalArea的值, 可是这些临时对象生成时却没有增加nTotalNumber和nTotalArea的值
静态成员函数中,不能访问非静态成员函数变量,也不能调用非静态成岩函数
void CRectangle::PrintTotal(){
cout << w << "," << nTotalNumber << "," << nTotalArea << endl;
}
CRectangle::PrintTotal();
// 解释不通,w到底属于哪一个对象