Topic : Introduction to C++ Classes
Author : Jonah
Page : 1 Next >>
Go to page :



C is what is known as a procedure-oriented language in which the programmer starts by describing the data and then writes procedures to manipulate the data. Eventually, however, programmers discovered that it made a program much clearer and easier to understand if they were able to group data with the operations (functions) that worked on that data. These groupings are known as objects, and languages such as C++ that use objects are known as object-oriented languages.

In C, data can be grouped together using structs like the following:



  struct date
  {
    int day;
    int month;
    int year;
  };


Data within a struct class could be easily accessed by using the . operator:



  date birthday;
  birthday.day = 12;
  birthday.month = 3;
  birthday.year = 1975;


In this way, the data can be easily grouped together, though if you want to validate that a date contained valid data, you would have to do it through an external function:



  bool validDate(int d, int m, int y)
  {
    if (d < 1 || d > 31) return 0;
    if (m < 1 || m > 12) return 0;
    if (y < 1900) return 0;

    return 1;
  }


Now, for a simple object like a date, this type of program design isn't so bad. However, when programs exceed 100,000 lines of code, they tend to have among the hundreds of functions those that perform the same task on different objects. This and many other complications introduced by procedure-oriented design make programs quite cumbersome to debug. These problems were what Bjarne Stroustrup set out to alleviate when he first invented "C with Classes" which later became C++. Functions can be grouped together with the data they work on, ensuring valid data and thus organizing code much better. An example C++ class for a date:


  class date
  {
  public:
    int day;
    int month;
    int year;

    bool validDate(int d, int m, int y)
    {
      if (d < 1 || d > 31) return 0;
      if (m < 1 || m > 12) return 0;
      if (y < 1900) return 0;

      return 1;
    }

    bool setDate(int d, int m, int y)
    {
      if (validDate(d, m, y))
      {
        day = d;
        month = m;
        year = y;

        return 1;
      }
      else
      {
        return 0;
      }
    }
  };


Now, this example introduces a very important part of C++ classes: that data validation can be built in. When creating a new date class, the user has no choice but to give values that are within the valid range for dates. A date class would protect against errors like this:

  date birthday;
  birthday.setDate (12, 3, 1975);
  birthday.setDate (4, 13, 1962);   // ERROR: month out of bounds

  cout << birthday.month;    // Outputs 3, previous month value


However, data validation does not totally protect the data as long as users can access the data using the syntax birthday.month. Thus follows another key aspect of object-oriented programming: private data members. In the class definition, the keyword private: specificies that the following data and/or functions are not accessible except from other functions in the class (public: specifies data and/or functions accessible outside the class). Within a well-designed C++ class, the only way to write to a data member is through accessor functions.


  class date
  {
  private:  // Data is kept private
    int day;
    int month;
    int year;

  public:  // Functions remain public
    bool validDate(int d, int m, int y)
    {
      if (d < 1 || d > 31) return 0;
      if (m < 1 || m > 12) return 0;
      if (y < 1900) return 0;

      return 1;
    }

    bool setDate(int d, int m, int y)
    {
      if (validDate(d, m, y))
      {
        day = d;
        month = m;
        year = y;

        return 1;
      }
      else
      {
        return 0;
      }
    }

    int getDay()
    {
      return day;
    }

    int getMonth()
    {
      return month;
    }

    int getYear()
    {
      return year;
    }
  };


The private status of the data members ensures their validity because the user must call setDate in order to modify their contents. To access the private members, one need only to call short accessor functions:


  date birthday;
  birthday.setDate (12, 3, 1975);

  cout << birthday.getMonth() << '-' << birthday.getDay() << '-' << birthday.getYear();


This code will output "3-12-1975", and it leaves out the possibility of modifying the data. For example, the following code would produce a compiler error:


  date birthday;
  birthday.month = 1;  // ERROR: accessing private data member


Writing to data can also be done through set functions (known as modifiers) similar to getDay and getMonth. The data is, of course, validated before being added to the class object, called an instance.


  class date
  {
  private:
    int day;
    int month;
    int year;

  public:
    bool validDate(int d, int m, int y)
    {
      if (d < 1 || d > 31) return 0;
      if (m < 1 || m > 12) return 0;
      if (y < 1900) return 0;

      return 1;
    }

    bool setDate(int d, int m, int y)
    {
      if (validDate(d, m, y))
      {
        day = d;
        month = m;
        year = y;

        return 1;
      }
      else
      {
        return 0;
      }
    }

    void setDay(int d)
    {
      if (d <1 || d > 31) return;  // Out of range
      day = d;
    }

    void setMonth(int m)
    {
      if (m < 1 || m > 12) return;  // Out of range
      month = m;
  


Page : 1 Next >>