静态成员变量和静态成员函数
静态成员:在定义前加了static关键字的成员。
class CRectangle
{
private:
int w, h;
static int nTotalArea; //静态成员变量
static int nTotalNumble;
public:
CRectangle(int w_, int h_);
~CRectangle();
static void PrintTotal(); //静态成员函数
};
//普通成员变量每个对象都有各自的一份,而静态成员变量一共就一份,为所有对象共享。
//普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。
//静态成员不需要通过对象就能访问。
//sizeof 运算符不会计算静态成员变量
class CMyclass
{
int n;
static int s;
};//则sizeof(CMyclass) = 4
//静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。
//静态成员函数本质上是全局函数。
//设置静态成员机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去像一个整体,易于理解和维护。
如何访问静态成员
1、类名::成员名
CRectangle::PrintTotal();
2、对象名.成员名
CRectangle r; r.PrintTotal();
3、指针->成员名
CRectangle *p = &r; p->PrintTotal();
4、引用.成员名
CRectangle &ref = r; int n = ref.nTotalNumble;
//静态成员示例
//考虑一个需要随时知道矩形总数和总面积的图形处理程序
//可以用全局变量来记录总数和总面积,用静态成员将这两个变量封装进类里面,这样更容易理解和维护。
class CRectangle
{
private:
int w, h;
static int nTotalArea; //静态成员变量
static int nTotalNumble;
public:
CRectangle(int w_, int h_);
//CRectangle(CRectangle &r);
~CRectangle();
static void PrintTotal(); //静态成员函数
};
/*
CRectangle类的缺陷:
在使用CRectangle类时,有时会调用复制构造函数生成临时的隐藏的CRectangle对象,如
1、调用一个以CRectangle类对象作为参数的函数时;
2、调用一个以CRectangle类对象作为返回值的函数时。
临时对象在消亡时会调用析构函数,减少nTotalArea和nTotalNumble的值,可是这些临时对象在生成时却没有增加nTotalArea和nTotalNumble的值。
解决办法:
为CRectangle类写一个调用复制构造函数
*/
CRectangle::CRectangle(int w_, int h_)
{
w = w_;
h = h_;
nTotalNumble++;
nTotalArea += w * h;
cout << "构造函数" << endl;
}
/*
CRectangle::CRectangle(CRectangle &r)
{
w = r.w;
h = r.h;
nTotalNumble++;
nTotalArea += w * h;
cout << "复制构造函数" << endl;
}
*/
CRectangle::~CRectangle()
{
nTotalNumble--;
nTotalArea -= w * h;
cout << "析构函数" << endl;
}
void CRectangle::PrintTotal()
{
cout << nTotalNumble << "," << nTotalArea << endl;
}
//在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数
/*
void CRectangle::PrintTotal()
{
cout << w << "," << nTotalNumble << "," << nTotalArea << endl; //错误:w是非静态成员变量
}
*/
//必须在定义类的文件中对静态成员变量进行一次说明或者初始化。否则编译能通过,但是链接不能通过。
int CRectangle::nTotalNumble = 0;
int CRectangle::nTotalArea = 0;
int main()
{
CRectangle r1(3, 3), r2(2, 2);
//cout << CRectangle::nTotalNumble; //错误:nTotalNumble为私有成员
CRectangle::PrintTotal();
r1.PrintTotal(); //等价于上一条语句
return 0;
}
/*
输出:
构造函数
构造函数
2,13
2,13
析构函数
析构函数
*/
//完整程序
class CRectangle
{
private:
int w, h;
static int nTotalArea;
static int nTotalNumble;
public:
CRectangle(int w_, int h_);
CRectangle(CRectangle &r);
~CRectangle();
static void PrintTotal();
};
CRectangle::CRectangle(int w_, int h_)
{
w = w_;
h = h_;
nTotalNumble++;
nTotalArea += w * h;
cout << "构造函数" << endl;
}
CRectangle::CRectangle(CRectangle &r)
{
w = c.w;
h = c.h;
nTotalNumble++;
nTotalArea += w * h;
cout << "复制构造函数" << endl;
}
CRectangle::~CRectangle()
{
nTotalNumble--;
nTotalArea -= w * h;
cout << "析构函数" << endl;
}
void CRectangle::PrintTotal()
{
cout << nTotalNumble << "," << nTotalArea << endl;
}
int CRectangle::nTotalNumble = 0;
int CRectangle::nTotalArea = 0;
int main()
{
CRectangle r1(3, 3), r2(2, 2);
CRectangle::PrintTotal();
return 0;
}