Section 1 - Static Member Data

The purpose of this second Module of your "welcome" week will be to review some specific topics that you'll need for the rest of the course.  We'll discuss static members, the this keyword, and a strategy for solving any OOP (Object-Oriented Programming) assignment.  This is an hour of prime-time online learning you won't want to miss.

1B.1.1 Static Member Data

A static class member is data defined in the class (not local to any method) that is qualified with the static keyword. Instance members are those that do not have the static keyword. Let's review the difference between these two kinds of member data.

Each time we instantiate an object, a new set of instance members is associated with that object, distinct from the instance members of other objects of the class. If you have two Card objects, you have two separate sets of data, one for each object.

In contrast, with static class members, there is only one datum associated with the entire class. If a member of a class is qualified by the static keyword, then no matter how many objects we instantiate, there is only one variable for that member, shared by all the objects of the class.

Why would we want such a communistic variable to be in our class?  There could be many reasons.  Here is an example of just one:

class Dog
{
public:
    static long population;  // static member
    long licenseNumber;      // instance member

    // other members ...
};

// later in the client or main method ...
Dog fido, lucy, watson;

We have declared  three new Dog objects - in other words, we instantiated 3 dogs. fido, lucy and watson each has its own personal copy of the licenseNumber data because licenseNumber is an instance member. They all share the one and only static member, population. This might be useful if, for instance, we wanted the population to be incremented each time a Dog was born, and decremented each time a dog died. It is a value that is common to all dogs in the Dog class. But the licenseNumber is unique to each instance:

fido.licenseNumber= 2312;

Clearly makes sense to us. It is saying that the licenseNumber field (I'll switch terminology to make sure you get used to both terms: member and field) in the fido instance is being set to 2312.  But what does:

watson.population++;

do? Well it clearly increments population, but since population is a static class member, there is only one such field for the entire class, and we are modifying that field. Since there is no reason to access this field through use of the watson reference, any more than there is to use the fido or lucy reference, we are offered the preferred method of access to static class members, through the class name:

Dog::population++;

Here we see more clearly what we are doing. Usually, you will want to use the class name when dereferencing a static class field.

1B.1.2 Initializing Static Member Data

As you know, we have a special method whose job it is to initialize all the instance member data for us.  That method is called a constructor, and it always has the same name as the name of the class.

Card card1, card2('5', spades);

These two objects now have their private data set because of the Card constructor (go back and see what that constructor did, if you forgot). 

Now that we have this concept of a static member, however, we have to figure out how to initialize it. Since it is a public member, we could have our client do it with a simple assignment statement, Dog::population = 0;,  but we should really make population private. Private instance data is usually initialized in the constructor, but we can't use a constructor for private static data . Can anyone tell us why that would mess up the concept of the Dog population?   C++ gives us a somewhat awkward way to initialize static class members.  After the class prototype, you would dereference the static member with the class name and initialize it like so:

class Dog
{
private:
    static long population;  // private static member
    long licenseNumber;     // private instance member

};

// initialize static member
long Dog::population = 0;

When the program starts, population will be set to 0.  That assignment is not visited ever again, so population can be adjusted as Dogs are created or destroyed.

Initializing a Static Array

Initialization of static arrays usually gives students panic attacks. Depending on the array and situation, you can do it in couple of different ways. If the array is reasonably short, you might fill it with data entirely in the initialization statement (outside the class prototype) as in:

string StudentClass::firstNames[] = {"elaine", "shailesh", "ying","sandra", "marlin"};

Another idea, especially if the array is long or the type is some massive object, is to use a pro forma initialization, which satisfies the compiler, but does nothing as far as initializing the array:

string StudentClass::firstNames[] = {0};

The 0 inside the braces will only work if it is compatible with the array element type. Surprisingly, 0 is compatible with string, char and several types not normally considered integer. If this does not work, simply supply some constant of the correct type (Days::monday), which might involve building an automatic object (Card('3', Card::clubs)). You have to accompany this with an initialization somehow, and there are a variety of ways to do it. Here are two common choices: