Create a C++ class

Digression: get the current local date and time in C++

We will need to know how to do this when we make our first C++ class, class date.

  1. time.C. The function localtime fills up a structure with information, and returns a pointer to this structure.
    (tm_sec might be a leap second.)

Create a C++ class

Pass some information (the ints year, month, day) down to the functions (print, next, etc.) that do all the work.

  1. 3ints.C. Hold the information about a date in three ints.
  2. struct.C. Hold the information about a date in one struct.
  3. Hold the information about a date in one object.
    1. obj1.C. An object with data members and (non-static) member functions
    2. obj2.C. Add a constructor and a static data member.
      Make the data member private.
      Exercise.
      Now that we have a constructor that throws exceptions, what would happen if the main function tried to create a
      	date d {2, 30, 2025};   //Bad date: there is no Ferbruary 30
      
      Can you catch the exception?
    3. Make another constructor for class date. This constructor will have no explicit arguments (i.e., arguments you can see), and will initialize the newborn date object to today’s date. The constructor will have to call the time and localtime functions.
    4. Initialization vs. assignment, first with plain old ints:
      	//Bad.
      
      	int i;      //Initialize i to unpredictable garbage.
      	i = 10;     //Assign a value to i, replacing the garbage.
      
      	//Better.
      
      	int i {10}; //Initialize i to 10.
      
      Now with data members in a constructor:
      //Bad.
      //This constructor for class date initializes the three data members of the
      //newborn object to unpredictable garbage.  Then it assigns values to the
      //data members, replacing the garbage.
      //Error checking omitted for brevity.
      
      date::date(int m, int d, int y)
      {
      	year = y;
      	month = m;
      	day = d;
      }
      
      //Better.
      //This constructor for class date initializes the three data members of the
      //newborn object to the values supplied by the user, y, m, d.
      //Error checking omitted for brevity.
      
      date::date(int m, int d, int y)
      	: year {y}, month {m}, day {d}
      {
      	//These curly braces are empty.
      	//Other than initializing the three data members, this constructor has
      	//no work to do (because we have omitted error checking). 
      }
      
    5. obj3.C. The three-argument constructor for class date will initialize the data members of the newborn date object, instead of filling them with unpredictable garbage and then assigning to them.
    6. Create separate header and implementation files, but put them in the same directory.
      1. #include with "double quotes" looks in your current directory for the header file.
      2. #include with <angle brackets> looks in the directory /usr/include/c++/14 for the header file (on our machine storm.cis.fordham.edu).
      Compile this three-file program (consisting of date.h, date.C, main.C) with
      c++ main.C date.C
      
      1. date.h. The header file for class date.
      2. date.C. The implementation file for class date contains the definitions for the member functions, friend functions, and static data members of the class.
      3. main.C. The rest of the C++ program that uses objects of class date.
      Here’s another three-file C++ program (consisting of the same date.h, date.C, and a different main2.C). You can compile this program with
      c++ main2.C date.C
      
    7. An explanation of the # lines at the start and end of date.h.

Re-implement class date with fewer data members

The data members are private, so no one else needs to know. Do not change the three arguments of the constructor, or the output of the print member function, even though the class no longer has three data members.

  1. Re-implement class date with two data members, year and day.
    1. date.h
    2. date.C
    3. main.C
  2. Re-implement class date with one data member, day.
    1. date.h
    2. date.C
    3. main.C

Class point

Like class date, we can think of class point primarily as a structure whose job it is to hold data members.

  1. Compile this three-file C++ program with
    c++ main.C point.C
    
    1. point.h
    2. point.C
    3. main.C
  2. An exercise I’d like to assign: re-implement class point with the private data members changed from x, y to r, theta. Make no change to the arguments of the constructor or the output of the print member function.
  3. Class height
    1. height.h
    2. height.C
    3. main.C

Class announcer, a class with a constructor and a destructor

  1. Unlike classes date and point, an object of class announcer hold very little data: just a name for itself. The purpose of an announcer object is not to hold data. Its purpose is to send out a birth announcement and a death announcement at the start and end of its life.

    New features:

    1. Class announcer has a static member function named howMany, that receives no invisible pointer. I guess I’m making a static member function sound the same as a friend function; we’ll have to talk more about this.
    2. We can initialize an int to a copy of the value on an existing int:
      	int edward {10};
      	int walter {edward};  //walter is born holding a copy of the value of ed
      
      Similarly, we can initialize an announcer to a copy of the value on an existing announcer. When this hapens, the copy constructor is called.
      	announcer edward {"Edward R. Murrow"};
      	announcer walter {edward};   //Call the copy constructor.
      
    Compile this three-file program with
    c++ main.C announcer.C
    
    1. announcer.h
    2. announcer.C
    3. main.C
    Methuselah is being born.
    Francis is being born.
    Fran is being born.
    Frank is being born.
    Abe is being born.
    Amy is being born.
    Ann is being born.
    At the end of function g, there are 7 objects.
    Ann is dying.
    Amy is dying.
    Abe is dying.
    Frank is dying.
    Fran is dying.
    Francis is dying.
    Methuselah is dying.
    

    Exercise. have the constructors and destructor for class announcer indent their output by the current value of announcer::count spaces. In the above program, for example, Ann’s birth and death announcements would be indented 7 spaces.

Events often happen in (nested) pairs

  1. Events often happen in pairs: open/close, lock/unlock, allocate/deallocte, appear/disappear, compress/decompress, encrypt/decrypt, etc.
    Constructors and destructors are triggered to make these pairs happen.
    Warning: error checking omitted for simplicity.
    1. constructor.c. A C program with a pair of explicit function calls, to fopen and fclose.
      Compile the program with cc instead of c++.
      cc constructor.c      (Should create file a.out)
      ls -l a.out
      -rw-r--r-- 1 mmeretzky staff 7 Feb  5 09:12 outfile.txt
      
      ./a.out               (Should create file outfile.txt)
      echo $?               (See the exit status producted by a.out)
      
      ls -l outfile.txt
      cat outfile.txt       (See what's in the file outfile.txt)
      rm outfile.txt
      
    2. constructor.C. A C++ program that constructs and destructs an object.
  2. A series of jobs often needs to be undone in the opposite order:
    1. Create a window.
      Create icons in the window.
      Do work.
      Destroy the icons.
      Destroy the window.
    2. Create a directory (or folder).
      Create files in the directory.
      Do work.
      Destroy the files.
      Destroy the directory.
    3. <HTML>
      <HEAD>
      <TITLE>
      This is the title.
      </TITLE>
      </HEAD>
      
      <BODY>
      <H1>
      This is heading 1.
      </H1>
      </BODY>
      </HTML>
      
    #include <iostream>
    
    int main()
    {
    	window w;     //Construct window w.
    	icon i0 {&w}  //Construct icon i0 and put it in the window.
    	icon i1 {&w}  //Construct icon i1 and put it in the window.
    	icon i2 {&w}  //Construct icon i2 and put it in the window.
    	work();
    	return EXIT_SUCCESS; //Destruct i2, i1, i0, w IN THAT ORDER.
    }
    
  3. Below is a blueprint for a big object containing smaller objects as its data members. When you call the constructor for class interval, it begins by automatically making two detours to the constructor for class date. After the detours, the {body} of the constructor for class interval is executed.

    Similarly, at the end of the destructor for class interval, we automatically call the destructor for the two date objects inside of the interval object that was just killed.

    class date {
    	int year;
    	int month;
    	int day;
    };
    
    class interval {
    	date begin;
    	date end;
    };
    
    //Definition of constructor for class interval
    
    interval::interval(int m1, int d1, int y1, int m2, int d2, int y2)
    	: begin {m1, d1, y1}, end {m2, d2, y2}
    {
    	//the body of the constructor for class interval
    }
    
    //Definition of constructor for class date
    
    date::date(int m, int d, int y)
    	: year {y}, month {m}, day {d}
    {
    	//the body of the constructor for class date
    }
    

Class stack

  1. An object that holds a stack of ints.
    1. stack.h
    2. stack.C
    3. main.C
    Compile this three-file program (consisting of stack.h, stack.C, and main.C) with
    c++ main.C stack.C
    
  2. stack.C. Don’t build your own class stack. The C++ Standard Library already has a template class stack. Write the name of the data type of your choice in the <angle brackets>.

A digression on unsigned integers

  1. unsigned.C and unsignedlong.C.

    Exercise.
    How many bytes are occupied by a long int or in a long unsigned int on our machine? What is the biggest and smallest value that can be stored in a variable of these data types? How about the data types long long int or long long unsigned int?

Class myrandom

The member function myrandom::rand in the file myrandom.C scrambles the value of the data member myrandom::next with a multiplication and an addition. For example, the first time we call myrandom::random, it changes the value of next from 1 to 1,103,527,590. Mathematicians have determined that the most random part of the resulting value consists of bits 30 through 16 inclusive. Here is 1,103,527,590 written in binary with these bits underlined:
01000001110001100111111010100110
The >> operator shifts this number 16 bits to the right,
0100000111000110
and the & operator allows only the 15 rightmost bits to survive. (0x7FFF is 111111111111111 in binary).

  00000000000000000100000111000110   (this is 1,103,527,590 shifted 16 places to the right)
& 00000000000000000111111111111111   (this mask is the 0x7FFF)
  00000000000000000100000111000110   (this is 16,838)

The final result is
100000111000110
which is 16,838 in decimal.

  1. An object that does only one thing for you. In other words, an object that has only one member function, not counting the constructor.
    1. myrandom.h
    2. myrandom.C
    3. main.C

Old homework

  1. prev
  2. three