某些情况,一个类中所有对象有一些公有成分。在面向对象的环境中,称之为类变量(class variables). C++中称为静态成员(static members). 有趣的是,一个静态数据成员只在一个单个的实例中存在,但这个实例被这个类中所有对象分享。静态数据成员的好例子是用来记录给定时刻一个确定类型的对象数目的变量。拿银行账户为例,账户持有人,金额数等是普通数据成员。然而利息率是个静态数据成员:
class Account{
public:
Account():customer_no(0),bal(0),int_warned(0){}
void open_account(long int customer){customer_no = customer;}
double balance() const {return bal;}
void transaction(double amount);
void daily_interest();
void add_interest();
static double current_interest(){return interest_rate;}
static void change_interest(double new_interest);
private:
long int customer_no;
double bal,int_earned;
static double interest_rate;
每个账户,有三个非静态数据成员。构造函数Account()用来初始化新的账户,三个非静态数据成员被置0。open_account用来开一个新账户。客户号码被用来作为开户参数。等等。
interest_rate是一个静态数据成员(保留字static). 也有另外两个成员函数,用来读取和改变当前的利息率。这两个函数特点是他们不处理单个账户,并且不用非静态变量。这样的成员函数称之为静态成员函数(static member functions).
静态数据成员只在一个单独的实例中存在,不是每个对象都有一个。我们可以在类的定义中声明一个静态数据成员,正如这里的interest_rate一样,但是静态数据成员的定义必须在类的外部。我们通常把他和单独的成员函数定义放在同一个文件中。这里我们可以将定义interest_rate防在一个名字为account.cpp的文件中。定义看起来像:
double Account::interest_rate = 0.0 ; //definition
注意此处不需要static。 静态的数据成员可以在定义时候初始化。此处被初始化为 0。构造函数不能用来初始化静态数据成员变量,并且析构函数也不能释放一个静态变量。
总结:
static type_name //declaration
定义在类外部: type class_name::name = initialization_value;
存在于单个实例,被所有类对象共享。
静态数据成员在private部分声明,因此只能在类内部访问,或者友元函数及友元类。在public中声明的静态数据成员对类外部可见。
下面例子显示如何使用静态数据成员:
test.h 文件:
#include <math.h>
#include <iostream>
using namespace std;
const double PI = 3.1415926;
class Particle{
public:
static long int parnum;
Particle(){radiuspar = 1.0e-3;densitypar = 1500;parnum++;};
double volume(){return 4.0/3.0 * PI * pow(radiuspar,3.0);};
private:
double radiuspar;
double densitypar;
};
long int Particle::parnum = 0;
test.cpp文件:
#include "test.h"
int main()
{
for(int i=0;i<1000;i++)
{
Particle();
}
cout<<"total particle number: "<<Particle::parnum<<std::endl;
}
如果一个函数被声明为静态成员函数。实质就是此函数将独立存在于任何特别的类的对象。即使没有任何类的对象存在,静态的成员函数也可以被调用。静态成员函数能够用类名加::进行访问。
静态成员函数不能访问this指针。下面是个修改前面例子使用静态成员函数的例子:
#include <math.h>
#include <iostream>
using namespace std;
const double PI = 3.1415926;
class Particle{
public:
static long int parnum;
Particle(){radiuspar = 1.0e-3;densitypar = 1500;parnum++;};
double volume(){return 4.0/3.0 * PI * pow(radiuspar,3.0);};
static long int obtainparnum(){return parnum;};
private:
double radiuspar;
double densitypar;
};
long int Particle::parnum = 0;
#include "staticmem.h"
int main()
{
cout<<"total particle number: "<<Particle::obtainparnum()<<std::endl;
for(int i=0;i<1000;i++)
{
Particle();
}
cout<<"total particle number: "<<Particle::obtainparnum()<<std::endl;
}