When a data member is declared static, only one copy of it is allocated, no matter how many instances of the class are declared. However, it can be treated like an ordinary data member by the class's member functions. If it is declared private, only the member functions can access it. For example, here's a declaration of a SavingsAccount class that contains a static member called currentRate:
class SavingsAccount
{
public:
SavingsAccount();
void earnInterest() { total += currentRate * total; }
//...
private:
char name[30];
float total;
static float currentRate;
//...
};
Only one copy of currentRate exists, and it is accessible to all SavingsAccount objects. Whenever the earnInterest member is called for any SavingsAccount object, the same value of currentRate is used. This is illustrated in Figure 6.1.
You can declare a static member public, making it visible to the rest of the program. You can then access it as if it were an ordinary data member of an object.
For example, if currentRate were a public member, you could access it as follows:
// If currentRate were a public member
void main()
{
SavingsAccount myAccount;
myAccount.currentRate = 0.000154;
}
However, this syntax is misleading, because it implies that only the interest rate of myAccount is being modified, when in fact the interest rate of all SavingsAccount objects is being modified. A better way of referring to a static member is to prefix its name with the class name and the scope resolution operator. For example:
// If currentRate were a public member
void main()
{
SavingsAccount::currentRate = 0.000154;
}
This syntax reflects the fact that the value being modified applies to the class as a whole, rather than an individual object. You can use this syntax even if you haven't declared any SavingsAccount objects; a static data member exists even if no instances of the class are declared.
You cannot initialize a static data member from within a constructor of the class, because the constructor may be called many times, and a variable can be initialized only once. A static data member must be initialized at file scope, as if it were a global variable. The access specifier for a static data member is not in effect during initialization; private static members are initialized in the same way as public ones. For example:
// SAVINGS.CPP
#include "savings.h"
// Initialize private static member at file scope
float SavingsAccount::currentRate = 0.0001;
SavingsAccount::SavingsAccount()
{
// ...
}
// etc....
Notice that the initialization is not placed in a header file, because that file may be included more than once in a program. The initialization is placed in the source module that contains the definitions of the class's member functions. Also note that the type of the static member is specified, because it is an initialization rather than an assignment. The static member is being declared at that point, not inside the class.