INTRODUCTION TO CLASSES

The C++ programming language contains many standard data types. These include int, double, char, bool, string, etc. While these are useful, we often need to represent more complex objects with multiple parts, each possibly being a different type. The C++ language facilitates creating new data types with a construct called a Class.

A class is a generic description of a real-world object such as a car or a house. The class description of a car might include an int variable for the year the car was built, a string variable for the name of the manufacturer, another string variable for the model name, a bool variable to indicate if the car is a convertible or not, etc. Similarly, the class description of a house might include an int for the number of bedrooms, a double for the number of bathrooms (a full bathroom has a sink, toilet, and bathtub while a half bathroom only has a sink and a toilet), a bool variable to indicate if the house has a fireplace, etc.

The declaration of a C++ class for each of the above examples might look like this:

  class Car {                                 class House {
    public:                                     public:
      int year;                                   int bedrooms;
      string manufacturer, model;                 double bathrooms;
      bool isConvertible;                         bool hasFireplace;
  };                                          };

While classes often describe tangible, real-world objects, they also quite often describe intangible objects such as a fraction or a point on a Cartesian plane. Class declarations for these might look like this:

  class Fraction {                            class Point {
    public:                                     public:
      int numerator;                              double x;
      int denominator;                            double y;
  };                                          };

Notice the word public in each of the above examples. This means the variables or properties of these objects will be visible to other code using the objects. It is also possible to make an object's variables or properties private, which will be discussed in a future lesson.

Also notice each of the above class names begins with an upper-case letter, Car, House, Fraction, and Point. This is a standard programming convention that should be followed.

INSTANCES

Once a class definition has been written, it is possible to declare a variable that refers to a specific instance of the class. This is no different from creating an int, double, or any other type of variable. An int or double variable is created as follows, with the type name followed by a valid C++ variable name:

  int count, sum;
  double average;

Creating specific instances of the example classes above is quite similar:

  Car hisCar, herCar;
  House myHouse;
  Fraction small, medium, large;
  Point top, bottom;

Since these variables are objects with multiple properties, the individual properties are accessed with the following "dot operator":

  // Read the year of hisCar from the console.
  cin >> hisCar.year;

  // Display the number of bedrooms and bathrooms in myHouse
  //        formatted for a real estate listing.
  cout << myHouse.bedrooms << "BR/" << myHouse.bathrooms << "BA" << endl;

Using the dot operator, an object's properties can be used in the exact same ways any variable of that type could be used.

Individual instances of a class are also called objects.

CLASS MEMBER FUNCTIONS

In addition to the properties of an object, a class can also contain member functions, which are basically functions that operate within a specific instance of a class. For example, it might be useful to have a member function named GetValue in the Fraction class that returns the value of the fraction object as a double. To do this, first add a prototype for the member function in the class declaration:

  class Fraction {
    public:
      int numerator;
      int denominator;

      double GetValue();  // Calculate and return the fraction's value, as a double.
  };

The function definition is then written as follows:

  // Calculate and return the fraction's value, as a double.
  double Fraction::GetValue() {
    return (double)numerator / (double)denominator;
  }

This looks like any other function, but notice the Fraction:: before the name GetValue. This indicates that GetValue is part of the Fraction class and therefore has access to the properties of a Fraction object.

It is important to understand that each specific instance of the Fraction class would respond differently to the GetValue member function, depending on the values stored in that specific instance's properties. Consider the following example:

  Fraction small, large;
  small.numerator = 1;
  small.denominator = 8;
  large.numerator = 3;
  large.denominator = 4;
  cout << "The small fraction value is " << small.GetValue() << endl;
  cout << "The large fraction value is " << large.GetValue() << endl;

The output of this example would be:

  The small fraction value is 0.125
  The large fraction value is 0.75

CONSTRUCTORS

Constructors are special member functions that execute automatically when an object is first created. These member functions do not return a value in the same way a regular function does, so their prototypes look a little different from a regular function:

  class Fraction {
    public:
      int numerator;
      int denominator;

      Fraction();         // Create a new Fraction object with default value 0/1.
      Fraction( int n, int d ); // Create a new Fraction object with value n/d.

      double GetValue();   // Calculate and return the fraction's value, as a double.
  };
Their definitions also do not include a return type:
  // A constructor with no parameters is called a Default Constructor.
  // A default constructor must choose reasonable values since none were specified.
  Fraction::Fraction() {
    numerator = 0;
    denominator = 1;
  }

  // A constructor with parameters specifies the initial values for the object.
  Fraction::Fraction( int n, int d ) {
    numerator = n;
    denominator = d;
  }

With the second constructor above, the previous example could be re-written as follows:

  Fraction small( 1, 8 );  // Sets the numerator and denominator values to 1 and 8.
  Fraction large( 3, 4 );  // Sets the numerator and denominator values to 3 and 4.
  cout << "The small fraction value is " << small.GetValue() << endl;
  cout << "The large fraction value is " << large.GetValue() << endl;

FURTHER READING

There is much more to learn about classes and objects, but this is a good start. Following are a few additional resources that may be useful: