静态成员:
1:在定义前面加了static关键字的成员。
2:普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。
3:sizeof 运算符不会计算静态成员变量。
4:普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。
5:因此静态成员不需要通过对象就能访问。
6:在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。
定义静态成员:
class CRectangle
{
private:
int w, h;
static int nTotalArea; //静态成员变量
static int nTotalNumber;
public:
CRectangle(int w_,int h_);
~CRectangle();
static void PrintTotal(); //静态成员函数
};
访问静态成员:
-
1:类名::成员名
CRectangle::PrintTotal();
-
2:对象名.成员名
-
CRectangle r;
-
r.PrintTotal();
-
-
3:指针->成员名
-
CRectangle * p = &r;
-
p->PrintTotal();
-
-
4 :指针->成员名
-
CRectangle & ref = r;
-
int n = ref.nTotalNumber;
-
注意:
1:静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。
2:静态成员函数本质上是全局函数。
3:设置静态成员这种机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去像一个整体,易于维护和理解
静态成员示例:
考虑一个需要随时知道矩形总数和总面积的图形处理程序。
可以用全局变量来记录总数和总面积。
#include <stdio.h>
#include <iostream>
using namespace std; //此句也可以在main函数体中出现。
class CRectangle
{
private:
int w, h;
static int nTotalArea; //矩形总面积
static int nTotalNumber; //矩形总数
public:
CRectangle(int w_,int h_);
~CRectangle();
static void PrintTotal();
CRectangle(CRectangle &r);
};
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; //打印面积与数目
}
CRectangle :: CRectangle(CRectangle & r ) //为类写一个复制构造函数,避免临时对象消亡时造成矩形总面积和数目减小。
{
w = r.w; h = r.h;
nTotalNumber ++;
nTotalArea += w * h;
}
int CRectangle::nTotalNumber = 0;
int CRectangle::nTotalArea = 0;
// 必须在定义类的文件中对静态成员变量进行一次说明
//或初始化。否则编译能通过,链接不能通过。
int main()
{
CRectangle r1(3,3), r2(2,2);
//cout << CRectangle::nTotalNumber; // Wrong , 私有
CRectangle::PrintTotal();
r1.PrintTotal();
return 0;
}
/*输出结果:
2,13
2,13*/