C++ Class Part 2

By Terry Norton

We now start getting to more complicated material. Building on what we learned in Chapter 3, data types, we now learn how to create far more powerful types for use in program control. We also begin learning about Pointers which help use the full power of C++.

Chapter 4 Compound Types
After reading Chapter 4, you should understand the following concepts:
 * Arrays, enumeration, structures, unions, and pointers
 * Dynamic memory and why it is used
 * Basic management of dynamic memory with new and delete
 * String input and output using basic istream and ostream classes and member functions
 * Null terminated strings versus arrays of characters
 * Enumeration variables and ranges of values
 * Type of memory use in C++ and its scope
 * Referencing members of static and dynamic structures

Static Arrays
Arrays provide the C++ programmer with flexibility in working with data. This section introduces concepts of data management. The full benefit of arrays will be realized when we later learn about loops. As you read, here are the array main points: An array is very simple. So far you are used to creating a single variable, such as int money. If you wanted more, you might make more variables, like money1, money2, money3, etc. However, the array lets you make a bunch of variables in one shot. So you could do int money[4]</tt> instead, which makes 4 money variables. So now to get the value, or data, stored in the second money variable you would do a cout << money[1];</tt>. NOTE: Do not use  </tt> with OpenWatcom, no such file. Use  </tt> or <string.h></tt>
 * Used for multiple values of the same data type
 * Creating an array
 * Derived types: based on other types
 * Access to array members
 * sizeof</tt> returns number of bytes in an array
 * Initializing arrays

Strings
Strings is a further case in the use of arrays. The main points for strings:
 * A special form of array
 * Series of characters stored in consecutive bytes of memory
 * Null terminated string versus an array of char</tt>
 * Using quoted strings to initialize, which automatically includes the null terminator
 * Concatenation of strings separated only by whitespace
 * String input; using cin</tt> member functions getline</tt> and get</tt>

Line-Oriented Input: getline</tt> and get</tt>
Strings in arrays are simple enough, one character in each element of an array, and at the end the null character "\0"</tt>. getline</tt> and get</tt> are Class member functions. They write this in the book like it's a back page item, but C++ is about Classes, and I want to point this out at every opportunity. The Class, istream</tt> (defined in the file <tt>iostream</tt>), has functions in it. <tt>getline</tt> and <tt>get</tt> are two of them. They are called members functions because they are part of the <tt>istream</tt> Class. To use these member functions, an object of the <tt>istream</tt> Class, <tt>cin</tt>, has to be a sent message to use them. <tt>cin.getline(name, ArSize)</tt> in Listing 4.4 does this. All this will really become apparent when we start creating our own Classes and defining member functions in them.

On page 108 you find the word concatenate. You will see this a lot in programming, so burn it into your memory. It just means join, but they have to be fancy.

Introducing Structures
Structures are the first hint of how Classes are created. Structures can hold different types of data, such as <tt>int</tt>, <tt>float</tt>, <tt>char</tt>, etc., all at the same time, as opposed to arrays which can only hold one type of data in its elements.

The main points for the C++ Structure:
 * It's a derived data type that contains various data items related to an object
 * An array of structures to contain data about several related objects
 * Creating a structure - define a structure description - create a structure data object (variable)
 * Referencing structure members

The structure is a user-defined type. You create it and name it. Just like an <tt>int</tt> or a <tt>char</tt> is a type already supplied for your use, when you make a structure you are creating a type to suite your purposes, then using it just like any of the other fundamental types that C++ already supplies.

Listing 4.7 is starting to get into some good stuff here. Even though these are Structure objects and not Class objects, the method used to access the data stored in the structure objects show how simple it is to get data from an object, such as pal.name in the example.

On page 116, they're showing a structure type declaration. It may look complicated, but it's just as simple and declaring any other data type. I'll show something you're familiar with: int cost, change;

Here I've created two variables of type <tt>int</tt>. The structure type variables are being created the same way on page 116, but with a little more structure info: struct perks { int key_number; char car[12]; } mr_smith, ms_jones;

I've put the declaration all on one line to show the comparison between the two declarations. Here we have created a structure called <tt>perks</tt>. <tt>perks</tt> is now a type, as <tt>int</tt> is a type. In the brackets is the declarations for what's in a <tt>perks</tt> type, an <tt>int</tt> and a <tt>char</tt> Right after the "<tt>}/</tt>" is the names of the variables created, <tt>mr_smith</tt> and <tt>ms_jones</tt>, just like <tt>cost</tt> and <tt>change</tt> were variables we created. Both these variables are of the <tt>perks</tt> type, just like <tt>cost</tt> and <tt>change</tt> are variables of the int type. <tt>perks</tt> just happens to be a structure, whereas <tt>int</tt> is an integer. If you have questions, please ask.

A little tidbit of info in the few sentences at the top of page 117. C++ structures can have member functions as well as member variables. C can only have member variables. What you will see in C++ is that a Class is basically a C++ structure.

Enumerations
This is a user-defined type. An enum variable can only be assigned a value that the user has specified when the enum was defined. In other words, when you define an enumeration, you have created some constants. Only the constants, or the value that you assigned to the constants, can be assigned to a enumeration variable, if you infact ever create an enum variable. You may just decide to use the constants directly in your program. For example, you can give the days of the week a constant value: enum {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; Sunday is 0, Monday is 1, etc. Any time you use Sunday the value 0 is substituted in your program: int today = Sunday; The variable today how has the value 0. The alternative to defining with an enum is like this: const int Sunday = 0; const int Monday = 1; const int Tuesday = 2; ... This is much more awkward than just using an enum. If you do define an actual enum variable, then the variable can only have a value that has been defined in the enum: enum day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; The type <tt>day</tt> can now be used to define a variable: day today = Sunday; The variable today can only be assigned one of the constants defined in the day enumeration.

Pointers and the Free Store
We are now going to get into a subject that may appear difficult, simply because it causes you to think from a different point of view. Let's do this, you have a quarter in your hand with the heads side showing. You can look at it and tell it's a quarter. However, if you turn it over so the tails side shows, can you still tell it's a quarter? Of course you can because you've already learned to view it from two different views. Variables can also be viewed from two different views.

So far you've learned, in the Twilight Zone, that a mailbox (memory address in my computer) can be given a name (variable name). I called my address Norton. So my mailbox has the variable name Norton on it. I didn't actually mention my address (the memory address) in Lesson one, but it is 10 (10 is my initials, Terry E. Norton). So the number on my box is 10, and the name on my box is Norton. The Twilight Zone mailman has learned that he can deliver mail to my house by knowing either my address, 10, or by the name on the box, Norton.

If you also recall, when my mailbox was opened, there was 54 on a piece of paper inside (my age). So to review, what we have here is a mailbox with the address 10, a name of Norton, and 54 in it (54 is an int in my mailbox). Simple, right? Anyone that wants to come to the Twilight Zone to find where I live can do it on this street by knowing my address or my name, and they can see what's in my mailbox (memory address).

You can easily get the value from the variable by: cout << Norton;

This will show 54 on my screen. The address of Norton is the memory address 10. So I can also get 54 if I want by looking at the memory address directly instead of using the name I gave it of Norton. Sound simple enough? Well, that's what we're going to do with a little item called a pointer. A pointer is a variable that contains, or points to, the memory address. Piece of cake, I just point to 10 and I can get the value 54.

What makes pointers appear so difficult is simply the way it looks on paper. For some reason, someone got the great idea to use the symbol "<tt> * </tt>" for pointers, which just happens to be the symbol for multiplication. So when you see it on paper mixed in with a bunch of words, it just doesn't want to sink in, it looks hard.

With pointers we are about to get into effective management in C++. The main topics in this section of the book are:


 * Ordinary variables: the value is the named quantity and the location as the derived quantity
 * Pointer variables: the location is the named quantity and the value is the derived quantity
 * Static binding and Dynamic binding
 * The address operator: <tt>&</tt>
 * Indirect value or dereferencing operator: <tt> * </tt>
 * Declaring and initializing pointers
 * Pointers and numbers

If you totally understand pointers as explained in the book, celebrate! I had to reread this stuff over several times until I could look at it and believe I understood it well enough to move on. I realize my little trip into the Twilight Zone is rather odd, but it has helped sink this material into my uncooperative gray matter. But it's still difficult seeing the dereferencing operator, <tt> * </tt>, splattered all over some code. I tend to go numb. Just bear with me a little more as I relate this to my Twilight Zone address.

int Norton ;       //creates a variable for the name on my mailbox Norton = 54;       //assigns my age to my mailbox variable cout << Norton;    //this displays my age 54

So far that's the easy part.

int * p_Norton;      //creates a pointer-to-int p_Norton = &Norton;  //gets the address, 10, where my age is stored and assigns it to the pointer cout << p_Norton;    //this displays 10 on my screen cout << *p_Norton;   //this displays my age 54

</tt> Therefore, <tt>Norton</tt> and <tt> *p_Norton </tt> are exactly the same.

Allocating Memory with <tt>new</tt>
The problem with starting a program is that there is just a limited amount of memory allocated to the stack and program memory. Ever hear of a stack overflow as a program crashes? A program should be able to use all that extra memory we all have in our computers now. All that extra, unused memory is called the heap, or free store. The heap can't have named variables, so to use the heap and know where info is stored, you need a pointer to get at the info. This is where the new operator is used, to use some of the heap while the program is running. This is where pointers come into play instead of named variables.

Remember, just above, I said Norton and <tt> *p_Norton </tt> are exactly the same? <tt>p_Norton is a pointer</tt>. It points to the memory location that contains the information, 54, that we seek. To get at the information, we take the pointer and dereference it by placing the dereferencing operator in front of the pointer like this, <tt> *p_Norton </tt>. Technically, you could say <tt> *p_Norton </tt> is the variable name for the heap memory, just like Norton is for the stack memory. Therefore, nt * p_Norton = new int; >

creates a new memory location in heap memory to hold an <tt>int</tt>. <tt>p_Norton</tt> is the pointer (of type point-to-int) that holds the new memory location. <tt> *p_Norton </tt> holds the data, 54. Where Norton was the variable name in the stack, holding the data 54, we now have <tt> *p_Norton </tt> in the heap holding the data.

Using <tt>new</tt> to Create Dynamic Arrays
Reviewing a little about arrays, int price[100];  //creates an array of 100 int variables </tt>

The price array is created on the stack, and is created at compile time whether you use it or not, static binding. The stack has limited memory, creating it on the heap is better. Create it with <tt>new</tt> when you need it, dynamic binding. int * price = new int [100]; Now the array has been created on the heap, or free store, of memory, and price is a pointer to the first element of the array.

Now for a curve ball. You just learned about pointers and how to dereference a pointer to get the value. With arrays made with <tt>new</tt> you can't use the dereference operator "<tt> * </tt>" to get the value in an element. We are to treat the pointer name as the array name.

Just to see what would happen, I compiled arraynew.cpp (page 134) first to make sure it ran properly, it does. I then changed the source so that p3[0] = 0.2; looked like *p3[0] = 0.2;

This won't compile, so do NOT use the dereference operator with arrays. The book goes on to explain why with the addpntrs.cpp example (page 135). At the top of page 139 the book says array notation is a second way to dereference a pointer.

Pointers and Strings
There are a lot of examples in the book covering strings. The main point to remember is that a string assigned to a pointer behaves like regular arrays do, with one difference. When you pass a string pointer to cout, cout continues to print out the contents of memory until it reaches a null character '\0'.

Using <tt>new</tt> to Create Dynamic Structures
NOTE: The example <tt>newstrct.cpp</tt> needs to have: delete ps; added before the return statement.

Using pointers with structures requires a slightly modified operator to access the data stored in a structure. This is the main point for this section of the book. With a named structure, use the "." (period) operator, with a pointer to a structure, use the "->" operator.

This has been a fairly long chapter covering quite a few items. The main item has been pointers and how they work, and how to use them. Pointers could be the most difficult material to master. For those of you coming from REXX, like me (even if only a short time), thinking backward to get data through pointers has been the most difficult to visualize. For total programming newbies, you probably will have an easier time since you aren't dragging old programming ideas along.

Questions for Chapter 4
True or False
 * 1) An array can contain any combination of data types.
 * 2) <tt>char animal[ ] = {"horse", \0}</tt> is a valid initialization of a string array.
 * 3) An array of <tt>char</tt> is a string only if a null terminator is the last character.
 * 4) <tt>cin</tt> stops accepting input to the current variable when <tt>\0</tt> is received from the keyboard.
 * 5) If memory is exhausted, <tt>int* stuff = new int;</tt> will return a null pointer.