> ### Appendix 1, Section 3
> Classes and Objects in C++

> C++ IS BASED ON AN EARLIER PROGRAMMING LANGUAGE called C. The main distinguishing feature of C++ is its support for object-oriented programming with classes and objects. (Although, in fact, C++ adds many other features to C as well.)

> Classes in Java are modeled on classes in C++, but with many differences. The most obvious of these is due to the distinction between declaration and definition in C++. (See Section 1.) In C++, a class has two distinct components, which can be -- and most often are -- placed in different files. First of all, there is the class declaration, which is similar to a class in Java except that it omits the definitions of the methods. The class declaration contains only what are called prototypes for the methods. It also declares any variables that belong to the class. The class declaration is generally placed in a header file so that it can be used easily by other parts of the program. The second component of the class consists of the actual definitions of the class's methods. These definitions are separate from the class declaration, and usually occur in a separate file.

> Here, for example, is a simple C++ class declaration:

>                class SimpleCalc {

>                        // A class for computing some statistics about
>                        // a list of numbers; the numbers are entered
>                        // into the data set one-by-one by calling the
>                        // method enter().

>                      int count;     // Number of items that have been entered.
>                      double sum;    // The sum of items that have been entered.
>                      double sqSum;  // The sum of the squares of all the items
>                                     //     that have been entered so far.

>                    public:  // The following members of the class are
>                             //     visible from outside the class.

>                      SimpleCalc();      // Constructor

>                      void enter(double dataItem);  // Adds dataItem to the data set.

>                      int getCount();    // Returns the number of items that
>                                         //    have been entered into the data set.

>                      double getMean();  // Gets the average of the items that
>                                         //    have been entered so far.

>                      double getSD();    // Gets the standard deviation.

>                      void clear();      // Clears the data set, resets count to zero.

>                }; // end of declaration of class SimpleCalc

> This should look mostly familiar from Java, except for the omission of the bodies of the methods. The syntax for the "`public`" modifier is a bit different. Instead of being applied to individual items, the modifiers `public`, `private` and `protected` apply to groups of items. In the above example, all the methods that follow "`public:`" are public. Items at the beginning of a class, before any access modifier is specified, are `private` by default. (Also note the semicolon at the end of the class declaration, which is absolutely required. Making this semicolon optional was one of the things that the designers of Java did right.)

> You can apply the "`static`" modifier to individual methods and variables in a class, with the same meaning as in Java. Unfortunately, neither static nor instance variables can be given initial values in a class declaration. (This is one of Java's more substantial improvements on C++.) Instance variables should be initialized in a constructor. There is a way to do initialization of static variables, but it has to be done outside the class declaration, as part of the definition of the class.

> By the way, in addition to constructors, a C++ class can contain a special method called a destructor. Just as a constructor is called automatically by the system when an object is first created, a destructor is called by the system when the object is destroyed. For an object created with the `new` operator, this happens when the object is explicitly deleted with the `delete` operator. For objects that are not created with the `new` operator, the system is responsible for making sure that the object is destroyed at the appropriate time.

> The purpose of a destructor is to do any cleanup that is necessary when the object is destroyed (beyond reclaiming the memory that is occupied by the object, which is being done in any case). For example, the destructor might close files that were opened in the constructor. Or if the constructor created an object with the `new` operator, the destructor can apply the `delete` operator to that object.

> The name for a destructor is the same as the name of the class, preceded by the character '~'. A destructor for the `SimpleCalc` class would be named `~SimpleCalc`. (Java does not have destructors. However, a class in Java can contain a "`finalizer()`" method which serves a similar purpose.)

> Now, let's say that the declaration of the class `SimpleCalc` is in a header file named `SimpleCalc.h`. To complete the definition of the class, you would write another file -- probably called `SimpleCalc.cpp` or `SimpleCalc.cc` -- to give the definition of each of the methods in the class. Here's what would go in that file:

>                #include "SimpleCalc.h"
>                #include "math.h"

>                SimpleCalc::SimpleCalc() {
>                   count = 0;  // initialize the instance variables
>                   sum = 0;
>                   sqSum = 0;
>                }

>                void SimpleCalc::enter(double dataItem) {
>                   count++;
>                   sum += dataItem;
>                   sqSum += dataItem * dataItem;
>                }

>                int SimpleCalc::getCount() {
>                   return count;
>                }

>                double SimpleCalc::getMean() {
>                   return sum / count;
>                }

>                double SimpleCalc::getSD() {
>                   double mean = getMean();
>                   return sqrt( (1.0/count) * (sqSum - count * mean * mean) );
>                }

>                void SimpleCalc::clear() {
>                   count = 0;
>                   sum = 0;
>                   sqSum = 0;
>                }

> The first line of the file might surprise you. To compile the definition of the class methods, the compiler must know the complete declaration of the class. However, the C++ compiler never goes out and looks for information -- if it needs to know something that's in another file, then that file must be explicitly `#included`. So in this case, the header file `SimpleCalc.h`, which contains the declaration of the class, must be included.

> The second line, which `#includes` `math.h`, is required since `math.h` declares the `sqrt` function, which is used later in the file.

> The rest of the file consists of definitions for the six methods of `SimpleCalc`, counting the constructor. The only surprise here is that the name of each method is preceded by "`SimpleCalc::`". This identifies the definition as a method in the class `SimpleCalc`, rather than an independent subroutine. (The same notation, by the way, is used to access static members of a class. If `SimpleCalc` had a static variable named `data`, then outside the class it would be called `SimpleCalc::data`.)

> To finish up this example, here is a main program that uses the class, `SimpleCalc`. This would be in yet another file, perhaps named `main.cpp`. Note that it includes the header file `SimpleCalc.h`, which declares the class, but it does not include the definitions of the methods in the class, which are defined in the file `SimpleCalc.cpp`. These definitions are inside the "black box," and the main program doesn't need to know them. This program also uses the standard `iostream.h` header file to get access to the standard input and output streams, `cout` and `cin`.

>               #include "SimpleCalc.h"
>               #include "iostream.h"

>               main() {  // Main routine for the program.
>                         // Reads a list of numbers input by the user and
>                         // prints some simple statistics about the data.

>                  SimpleCalc calc;  // A SimpleCalc object to keep track
>                                    // of the data and compute the statistics.

>                  double x;   // A number entered by the user

>                  cout << "Enter some numbers.\n";
>                  cout << "Enter 0 to end.\n";

>                  do {
>                     cout << "  ? ";
>                     cin >> x;
>                     if (x != 0)
>                        calc.enter(x);
>                  } while (x != 0);

>                  cout << "You entered " << calc.getCount() << " numbers.\n";
>                  cout << "The average is " << calc.getMean() << ".\n";
>                  cout << "The standard deviation is " << calc.getSD() << ".\n";

>               }

> One important note is that the `SimpleCalc` object is created without using the `new` operator. In C++, a variable of object type, such as `calc` in this program, holds an object and not just a reference to an object. When such a variable is declared, an object is constructed and is stored in the variable. If the constructor requires parameters, they are provided as part of the variable declaration. For example, if the constructor in the class `SimpleCalc` required a parameter of type `int`, the declaration of `calc` would take this form:

>                   SimpleCalc calc(10);

> This is very different from Java. To get behavior more similar to what happens in Java, you have to use pointers to objects. For example, you could declare a variable `pcalc` that can hold a pointer to an object of type `SimpleCalc`:

>                   SimpleCalc *pcalc;

> In this case, just as in Java, this does not automatically create an object for `pcalc` to point to. For that you need the `new` operator:

>                   pcalc = new SimpleCalc();

> One odd thing that happens in C++ is that when you use a pointer to refer to an object, the notation for referring to instance variables and methods in the object also changes. Since `*pcalc` is the name of the object, you could say "`(*pcalc).clear()`" to refer to the `clear()` method in the object `*pcalc`. (The parentheses are necessary because `*pcalc.clear()` would be taken to mean *(pcalc.clear()). The '.' operation has higher precedence than the '*' operation.) The notation `(*pcalc).clear()` is rarely used, however, because the alternative notation "`pcalc->clear()`" is defined to mean the same thing. The operator "`->`" means "first follow the pointer to find an object, then access a member of the object.

> To have real object-oriented programming, of course, you have to have inheritance and polymorphism. Inheritance is easy. Just as in Java, you can declare one class to be a subclass of another. For example, to declare `ComplexCalc` to be a so-called "public" subclass of `SimpleCalc`, you would say:

>                     class ComplexCalc : public SimpleCalc {
>                       .
>                       .  // (additions and modification to stuff
>                       .  //   that is inherited from SimpleCalc)
>                       .
>                     }

> This would be equivalent to saying in Java that `ComplexCalc extends SimpleCalc`. Just as in Java, `ComplexCalc` inherits everything that is contained in the definition of `SimpleCalc` and it can modify and add to what it inherits. (There are also "private" and "protected" subclasses, but I won't try to explain them here.)

> Polymorphism, unfortunately, is a bit murky in C++. First of all, polymorphism works only with pointer variables and variables of reference type, never with variables that contain actual objects. A pointer variable can point to objects belonging to some specified class or to a subclass of that class. So, you would expect a subroutine call statement of the form `ptr->doSomething()` to be polymorphic. That is, you would expect that the `doSomething` method that is called will depend on the type of object that `ptr` is actually pointing to at the time the statement is executed. However, this will happen only for so-called virtual methods. You can declare a method to be virtual by adding the modifier `virtual` to the declaration of the method. What you are saying when you do this is that the method is meant to be polymorphic. If you think this is confusing, don't worry too much about it -- I've talked to people who had studied C++ for quite a while and who still could not correctly explain exactly what `virtual` means. Just remember that if you want to do real object-oriented programming in C++, then you have to use pointers and virtual methods. You might also remember this as one more reason to appreciate Java, where polymorphism is automatic and natural.

> This has been just a brief introduction to classes in C++, which have many features that I haven't even mentioned. More generally, C++ is a very large and complex language, which takes a long time to master. I certainly haven't told you enough about it to enable you to write serious programs in C++, but I hope I've given you some of the its general flavor and a sense of how it differs from Java.

> End of Appendix 1

| Previous Section | Appendix Index | Main Index ]