Section 3 - A Simple Class: Pet

6A.3.1 Dereferencing the object

Now that we have some Pet objects, how do we manage the individual data of those objects?  We do it through the object name.  If we want to manipulate, read or display the name of the Pet stored in mikesDog, we would access that data by using the name of the object followed by a period, followed by the name of the field that we want to access (in this case the petsName field):

mikesDog.petsName = "Jerry";

or, accessing the same field to do something different:

   cout << mikesDog.petsName;

So you see, this is how we get at the primitive data that lies deep within each object of our class.

Another way to think of this is as follows.  Whenever we instantiate a new Pet object, it is imbued with four data fields (as we described in the class definition: two strings, a double and a long).  If the object is called garfield because we declared the reference like so:

Pet garfield;

then we use the word garfield to get at the weight or petsName fields through the notation: garfield.weight or garfield.petsName.  Of course, garfield.petsName is probably the string "Garfield" or "Mr. Garfield".  Don't confuse this string stored inside the object (which can be anything we want and might change as the program progresses) with the object reference, garfield

Terminology

Using the object name to get at the field (or member) data this way is called dereferencing the field (or member).  We also say we are using the object to dereference the field or member.  Sometimes we say we are dereferencing the object to get at the field.  It all means the same thing.  We are using the object with a period followed by a field name.

6A.3.2 The Noisy Dog

With that introduction we can look at a complete (silly) program.

#include <iostream>
#include <string>
using namespace std;

// ------- class prototypes -------
class Pet
{
public:
// member data
string petsName;
string ownersName;
double weight;
long numberOfLimbs;
};

int main()
{
// declare a couple Pet objects
Pet mikesDog, noisyDog;

// fill in the fields or members of mikesDog
mikesDog.petsName = "Jerry of Westhampton";
mikesDog.ownersName = "Michael Loceff";
mikesDog.weight = 8.5;
mikesDog.numberOfLimbs = 4;

// show mikesDog to the user
cout <<  mikesDog.petsName << " is owned by "
<< mikesDog.ownersName << endl;

cout << mikesDog.petsName << " has "
<< mikesDog.numberOfLimbs << " limbs and weighs "
<< mikesDog.weight << " pounds\n\n";

// assign one reference to another
noisyDog = mikesDog;

// modify individual members
noisyDog.petsName = "chloe";
noisyDog.weight = 31.2;

// show noisyDog to the user
cout <<  noisyDog.petsName << " is owned by "
<< noisyDog.ownersName << endl;

cout << noisyDog.petsName << " has "
<< noisyDog.numberOfLimbs << " limbs and weighs "
<< noisyDog.weight << " pounds\n\n";
}

Here is a copy of the run:

Jerry of Westhampton is owned by Michael Loceff
Jerry of Westhampton has 4 limbs and weighs 8.5 pounds

chloe is owned by Michael Loceff
chloe has 4 limbs and weighs 31.2 pounds

Press any key to continue . . .

This program is unrealistic in a couple ways.  First, all of the Pet data is public.  This enables the client (by that, I mean main()) to access the data directly.  While that sounds harmless, actually it is quite dangerous.  One of the advantages of surrounding data with a class is that the class can protect the data from unskilled users or clients who might inadvertently damage the data.  A second unrealistic aspect of this example is that there are no methods (i.e., member functions) defined inside Pet.  This is related to the first issue in that, if we had methods, we could declare all the fields to be private and then design the methods so they could be used by the client to modify the data. By forcing the client to access the instance data through public methods (rather than giving it access to instance data directly as we did here) we could have protected  the class data against a malicious client.

6A.3.3 Instance Variables

The four members inside the Pet class are called instance variables for the class.

Every time a Pet object is instantiated in main() or some other client, that instance gets its own copy of all these fieldspetsName, ownersName, weight and numberOfLimbs.  That's why they are called instance variables - a new set is created every time a new instance of Pet is created. 

6A.3.4 Static Class Variables

If the keyword static had been  placed in front of any of the fields, then that field would be a static class member.  The result would be that new Pet instances would not get their own copy of those static members.  All the objects of the class Pet would share one copy of a static class variable.  We don't have any examples in class Pet of static class variables since all the data members are instance variables.