Abstract Data Types

The recurring polynomial example shows an example of an abstract data type--a set of data items (coefficients and degree) and fundamental operations on this set (read/print and others in project 1).

Object-Oriented Programming (OOP)

The basic idea is to combine these data and operations into a single unit--an object.

There are 3 key pieces to OOP:

  1. encapsulation--combine the data and the operations (methods) together (in an object).

  2. polymorphism--the same operation (method) is available in different types of objects. For example, the <<, >> and + operators are overloaded in that they work on different types.

  3. inheritance--one object is a descendent of an existing object.

In this course we will only concentrate on encapsulation of data and their operations. Later courses will focus on the other topics of OOP.

Encapsulation

Show three implementations for an ADT (draw pictures):

  1. data items and functions each are separate

  2. data items combined (structure) with functions each separate

  3. data items and functions combined into an object

Class

In C++, an object is declared as a class. A class may of data items and member functions. These member functions are called methods.

General format of a class:

class class_name {
  private:
    type definitions and variable decl. of data members that are private
    and can be used only by statements inside the class def.
  public:
    function prototypes of methods that are public and can be used by
    statements outside the class definition
};

Methods are then defined with the class name and a double colon proceeding the method declaration.

Polynomial Example Revisited

Group the data and functions as part of a single class:

class Polynomial {
  private:
    int wDegree;
    float rgCoeff[MAXCOEFF];
  public:
    void ReadPoly();
    void PrintPoly();
};

/*
 * /cs/cs2005/pub/example/polyclass.C -- treat a polynomial as a C++ class
 *
 * programmer -- Craig Wills
 *
 * date -- November 2, 1996
 *
 * modification history
 */

#define MAXCOEFF 10       /* maximum number of coefficients */

#include <iostream.h>

#define FALSE 0
#define TRUE 1
typedef short Boolean;

class Polynomial {
  private:
    int wDegree;
    float rgCoeff[MAXCOEFF];
  public:
    void ReadPoly();
    void PrintPoly();
};

void main()
{
    Polynomial poly;  // in C++ can just use the name of the class
    
    /* read in and print a polynomial */
    poly.ReadPoly();
    poly.PrintPoly();
}

/*
 * ReadPoly -- read and store the contents of a polynomial along with its
 *     degree.
 */
void Polynomial::ReadPoly()
{
    Boolean bOk;                /* is the degree ok? */
    int i;

    /* obtain the degree of the polynomial */
    bOk = FALSE;
    while (!bOk) {
        cout << "What is the degree of your polynomial? \n";
        cin >> wDegree;
        if ((wDegree < 0) || (wDegree >= MAXCOEFF))
            cout << wDegree << "is not in the allowed degree range of 0-"
                << MAXCOEFF-1 << "\n";
        else
            bOk = TRUE;
    }

    /* obtain the coefficients of the polynomial */
    for (i = wDegree; i >= 0; i--) {
        cout << "Enter the coefficient for the degree " << i << " term: ";
        cin >> rgCoeff[i];
    }
}    

/*
 * PrintPoly -- print the contents of a polynomial given the coefficient
 *    list and the polynomial degree (in a rather ugly manner).
 */
void Polynomial::PrintPoly()
{
    int i;

    cout << "f(x) =";
    for (i = wDegree; i >= 0; i--) {
        cout << " + " << rgCoeff[i] << "x^" << i;
    }
    cout << "\n";
}

Class Constructors and Destructors

There are two special member functions of a class. The constructor method always has the same name as the class. It is automatically called when the class is created.

The destructor method has the same name as the class preceded by a ~ (tilde). It is automatically called when the classes is destroyed (not relevant for us yet.

An example of a constructor is given in the following code.

/*
 * /cs/cs2005/pub/example/classexample.C -- C++ class example
 *
 * programmer -- Craig Wills
 *
 * date -- November 2, 1996
 *
 * modification history
 */

#define MAXEXAM 200       /* maximum number exam scores stored */

#include <iostream.h>

class Exams {
  private:
    int cnt;
    int rgExams[MAXEXAM];
  public:
    Exams();                // constructor function called when class created
    void AddExam(int);
    float Average();
};

void main()
{
    Exams exam;  // in C++ can just use the name of the class
    
    /* read in and print a polynomial */
    exam.AddExam(75);
    exam.AddExam(67);
    cout << "Current average: " << exam.Average() << "\n";
    exam.AddExam(92);
    exam.AddExam(61);
    cout << "Current average: " << exam.Average() << "\n";
}

/*
 * Exams -- constructor function called on class creation
 */
Exams::Exams()
{
    cnt = 0;                        // initialize count to zero
}    

/*
 * AddExam -- add the given exam score to the list
 */
void Exams::AddExam(int score)
{
    if (cnt <= MAXEXAM) {
        rgExams[cnt] = score;
        cnt++;
    }
}    

/*
 * Average -- return average of the current set of exam scores
 */
float Exams::Average()
{
    int i, sum = 0;

    if (cnt == 0)
        return(0.0);
    else {
        for (i = 0; i < cnt; i++)
            sum = sum + rgExams[i];
        return(float(sum)/cnt);        // use cast to do floating point divide
    }
}

The output for this program is:

> classexample
Current average: 71
Current average: 73.75