CSCE 121 Chapter 9

From Notes
Jump to navigation Jump to search
Begin Exam 2 Content

« previous | Wednesday, September 22, 2010 | next »

Classes

User-defined type that represents a noun concept

Data members in a class can be manipulated through function members

Example:

class X {   // class name is X
  public:   // accessible by all
    int m;  // data member
    int mf(int v) { int old = m; m = v; return old; }  // function member
  private:  // only accessible by functions in this class
    // functions
    // types
    // data
};

int main() {
  X var;
  var.m = 7;
  var.mf(9);  // returns 7;
}

Data is often best kept private, so class members are private by default.

Structs

Struct is a class where members are public by default

struct Date {
  int y, m, d;
}

Date my_birthday;

my_birthday.y = 12;
my_birthday.m = 27;
my_birthday.d = 1991;  // oops!  invalid date, but it's perfectly fine.

Helper Functions

struct Date {
  int y, m, d;
  // helper functions
  Date (Date& dd, int y, int m, int d); // check for valid date
  void add_day(int n);
}

Date my_birthday;          // This now throws an error because it does not initialize my_birthday
Date my_day(1991, 12, 27); // ok
my_day.add_day(5);         // should be January 1, 1992, but my_day.m is now 14

The notion of a "valid date" means that values have to be valid. Rules for what define "valid" values are called invariants.

If we can't think of a good invariant, we should probably use a struct


When defining a class, it's always a good idea to declare the class first, then define the details later.

// date.h
class Date {
  public:
    class Invalid {};
    Date(int y, int m, int d);
    void add_day(int n);
    int month();
    int day();
    int year();
  private:
    int y, m, d;
    bool check(int y, int m, int d);
};
// date.cpp
Date::Date(int yy, int mm, int dd) : y(yy), m(mm), d(dd) {
  if (!check(y, m, d)) throw Invalid();
};  // is the ';' necessary?

Date::add_day(int n) { /* ... */ };


Public/Private Debate

Segregation of public and private members keeps the code clean. Declare invariants

Enumerations

Declared enum; a very simple type with a set of values.

enum Month {
  jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
};

Numerically indexed from zero by default, but can be changed (see code above). Cannot assign by Month m = 7.

Can assign without type declaration to define constants:

enum { red, blue };

int color = red;


Const

class Date {
public:
  // ...
  int day() const { return d; }   // const member function not allowed to modify anything
  void add_day(int);              // non-const member is allowed to modify class data member
  // ...
};

Date d(2000, Date::jan, 20);
const Date cd(2001, Date::feb, 21);  // not allowed to change after initialized

cout << d.day() << " - " << cd.day() << endl;  // okay to get const member on const variable
d.add_day(1);   // okay
cd.add_day(1);  // not okay; cd is a const, and add_day is not a const member function


Classes (cont'd)

  • Minimal: as small as possible
  • Complete: and no smaller
  • Type Safe: beware of confusing argument orders
  • const Correct: use for get() functions


  • Default constructor when no constructor is declared inits to nothing
  • Copy constructor (default: copy member)
  • Copy assignment (default: copy members)
Date d;       // default
Date d2 = d;  // copy constructor
d = d2;       // copy assignment


Interfaces and "Helper Functions"

  • Keep it simple

Sometimes we need extra "helper functions" outside the class scope (non-member functions) like operators:

==, !=, next_weekday(), next_Sunday()

Operator Overloading

 Date next_Sunday(const Date& d) { /* ... */ }

bool operator==(const Date& a, const Date& b) {
  return a.year() == b.year() && a.month() == b.month() && a.day() == b.day();
}

bool operator!=(const Date& a, const Date& b) { return !(a==b); }

Almost all C++ operators can be defined with the operator##() function, where ## is the operator (+, -, *, /, ++, !=, etc.)