Section 2 - Static Methods

7A.2.1 Instance and Static Class Methods

This same static concept can be applied to class methods.  That is, we can place the static keyword in front of a class method to make it a static class method, in contrast to an instance method for that class.  What does the static keyword mean in this case?

Well, in our Dog class the static member population gives us a clue.  A candidate for a static method in the Dog class might  be a method called getPopulation().  This is a method that would return the population number to the client.  It certainly would not need to be dereferenced using a particular dog.  Why would we ask fido to give us the population information as opposed to lucy?  They'll both give us the same answer, and neither has any claim to being the reporter of this information.   So we see we would like to be able to use the class name to dereference the getPopulation() member.  And that's just how static methods are used.

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

public:
static int getPopulation();

};

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

// then, much later, with other class method definitions
int Dog::getPopulation()
{
return population;
}

Now, from main() or any other client:

int  main()
{
Dog fido, lucy, watson;

// any time, we can do this:
cout << "\n Pop. " << Dog::getPopulation() << endl;
}

7A.2.2 A Class of Geometric Shapes: Rectangle

Next, we create a class called Rectangle which consists of the two numbers width and height. In addition to those two numbers there will be several methods. Most of these methods will not have the static modifier in front of them, which makes them ordinary instance methodsInstance methods must be dereferenced through a particular object instance, and they usually operate on the private data of that one instance which is used to call them.  Thus, when we called

gal1.setMagnitude(13.5);

 we were asking the instance method setMagnitude() to operate on the private data of the Galaxy gal1

In class Rectangle we will also introduce a static class method, identified by the static modifier.  This method is not meant to be called by using any particular Rectangle object, but is dereferenced using the Rectangle class name, itself.

Before giving the full definition of the Rectangle class, let's just see how two of the method prototypes look and how they are used.  These are both going to be inside the Rectangle class.  First an instance method:

bool setWidthHeight(double w, double h);

Next a static class method:

static Rectangle whichIsBigger(Rectangle r1, Rectangle r2);

decorative metal frame building

The function setWidthHeight() will be used to assign values to the data members width and height. It makes sense that this is an instance method since it needs an object on which to work.  setWidthHeight() is a kind of accessor method because it accesses two of the private data of the class, width and height.

whichIsBigger() takes two Rectangle objects as arguments and returns a Rectangle object that is the larger of the two. (The word Rectangle in front of the method name is simply the return type of the method - instead of void or int, the return type is Rectangle.) Since all the data on which it needs to "think" is passed in as arguments, there is no logical reason why this should be an instance method.  We can sensibly use the class name, Rectangle, to dereference this method.  That's why we make it a static method, rather than an instance method.

As before, we can (probably in main()instantiateRectangle object thusly:

Rectangle r1;


then we may call the setWidthHeight() function by using this object as a handle:

r1.setWidthHeight(2, 5);

Now what do you suppose this function call does? Well that depends on how we define it, but you can guess that if we design it to behave rationally, it will set the width member and the height member to the values 2 and 5, respectively.

Which width and height members? The ones belonging to the data object r1. Why r1? Because we used r1 as a handle to call (or dereference) the member function setWidthHeight().

Next we can do the same thing for a second rectangle:

   Rectangle r2;  

then we may call the setWidthHeight() function by using this object as a handle:

r2.setWidthHeight(3, 4);

Now that we have two Rectangle instances, we can compare them with our static method whichIsBigger() .  We'll need a Rectangle object to capture the functional return:

Rectangle r3;

r3 = Rectangle::whichIsBigger(r1, r2);

Make sense? It probably would help if you saw the entire program and class definition.   We will do that soon.  First a little diversion on a new topic.