- 静态成员:在说明前面加了 static 关键字的成员
class Rectangle
{
private:
int w,h;
static int nTotalArea;//静态成员变量,被所有的同类对象所共享,修改了一个对象的属性,其他成员也一起跟着修改;
static int nTotalNumber;
public:
CRectangle(int w_,int h_)
~CRectangle();
static void PrintTotal();//静态成员函数
}
- 普通成员变量每个对象各自的一份,而静态成员变量一共就一份,为所有对象所共享。
sizeof 运算符不会计算 静态成员变量。
class CMyclass{
int n;
static int s;
};
//则sizeof(CMyclass)等于4
- 普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。
- 因此静态成员不需要通过对象就能访问。
如何访问静态成员
- 类名::成员名
CRectangle::PrintTotal();
- 类名::成员名
2)对象名.成员名
CRectangle r; r.PrintTotal();3)指针->成员名
CRectangle * p = &r; p->PrintTotal();4)引用、成员名
CRectangle & ref = r; int n = ref.nTotalNumber;
注意:以上方法虽然都是对象来调用的,但是并不意味着方法作用于这个对象。静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。
静态成员函数本质上是全局函数。
设置静态成员这种机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去行一个整体,易于理解和维护。
class CRectangle
{
private: int w,h;
static int nTottalArea;
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 CRectanle::nTotalNumber = 0;
int CRectanle::nTotalArea = 0;
int main()
{
CRectangle r1(3,3),r2(2,2);
CRectangle::PrintTotal();
r1 PrintTotal();
return();
}
- 在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。(因为静态成员函数不是作用于对象的,所以如果访问了非静态成员变量,系统不知道是哪个对象的?)
void CRectangle::PrintTotal()
{
//不允许这样写
cout<<w<<","<<...<<endl;
}
CRectangle::PrintTotal();//解释不通,w 到底是属于哪个对象的?
- 在使用 CRectangle 类的时候,有时候会调用复制构造函数生成临时的隐藏的 CRectangle 对象
- 调用一个以 CRectangle 类对象作为参数的函数时
- 调用一个以 CRectangle 类对象作为返回值的函数时
- 临时对象在消亡时会调用析构函数,减少nTotalNumber和 nTotalArea 的值,可是这些临时对象在生成时却没有增加 nTotalNumber 和 nTotalArea 的值。
- 解决方案:为 CRectangle 类写一个复制构造函数
CRectangle::CRectangle(CRectangle & r)
{
w = r.w; h =r.h;
nTotalNumber++;
nTotalArea +=w*h;
}