class CRectangle{
private:
int w,h;
static int nTotalArea; //静态成员变量
static int nTotalNumber; //静态成员变量
public:
static void PrintTotal (); //静态成员函数
};
普通成员变量每个对象有各自的一份,而静态成员变量只有一份,被所有同类对象共享。对象名.成员名等方式,指明要访问的成员变量是属于哪个对象的,或要调用的成员函数作用于哪个对象;访问静态成员时,则可以通过类名::成员名的方式访问,不需要指明被访问的成员属于哪个对象或作用于哪个对象。因此,甚至可以在还没有任何对象生成时就访问一个类的静态成员。对象名.成员名)其实也适用于静态成员,但效果和类名::成员名这种访问方式没有区别。
#include <iostream>
using namespace std;
class CRectangle
{
private:
int w, h;
static int totalArea; //矩形总面积
static int totalNumber; //矩形总数
public:
CRectangle(int w_, int h_);
~CRectangle();
static void PrintTotal();
};
CRectangle::CRectangle(int w_, int h_)
{
w = w_; h = h_;
totalNumber++; //有对象生成则增加总数
totalArea += w * h; //有对象生成则增加总面积
}
CRectangle::~CRectangle()
{
totalNumber--; //有对象消亡则减少总数
totalArea -= w*h; //有对象消亡则减少总而积
}
void CRectangle::PrintTotal()
{
cout << totalNumber << "," << totalArea << endl;
}
int CRectangle::totalNumber = 0;
int CRectangle::totalArea = 0;
//必须在定义类的文件中对静态成员变量进行一次声明 //或初始化,否则编译能通过,链接不能通过
int main()
{
CRectangle r1(3, 3), r2(2, 2);
//cout << CRectangle::totalNumber; //错误,totalNumber 是私有
CRectangle::PrintTotal();
r1.PrintTotal();
return 0;
}
程序的输出是:类名::,如第 29 行和第 30 行。声明的同时可以初始化。如果没有声明,那么程序编译时虽然不会报错,但是在链接(link)阶段会报告“标识符找不到”,不能生成.exe文件。
void CRectangle::PrintTotal()
{
cout << w << "," << totalNumber << "," << totalArea << endl; //错误
}
其中访问了非静态成员变量 w,这是不允许的,编译无法通过。因为如果用CRetangle::PrintTotal();这种形式调用 PrintTotal 函数,那就无法解释进入 PrintTotal 函数后,w 到底是属于哪个对象的。CRectangle rl(r2);这样的语句,那么就有一些 CRectangle 对象是用默认复制构造函数,而不是 CRec:tangle(int w_, int h) 进行初始化的。这些对象生成时没有增加 totalNumber 和 totalArea 的值,而消亡时却减少了 totalNumber 和 totalArea 的 值,这显然是有问题的。
CRectangle::CRectangle(CRectangle & r)
{
totalNumber++;
totalArea += r.w * r.h;
w = r.w; h = r.h;
}
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有