CS 2413 001 Summer 2000
Homework #1 Solutions


  1. What is the output of each of the following programs?

    1. % cat passbycopy.cpp
      #include <iostream.h>
      
      int func1 (int a, int b)
      { // func1
          a = a * 2;
          b = b * 3;
          return a + b;
      } // func1
      
      int main ()
      { // main
          int x = 5, y = 10, z;
      
          z = func1(x, y);
          cout << "x = " << x << ", y = " << y << ", z = " << z << endl;
      } // main
      % g++ -o passbycopy passbycopy.cpp
      % passbycopy
      x = 5, y = 10, z = 40
      
      Answer: x = 5, y = 10, z = 40

    2. % cat passbyref.cpp
      #include <iostream.h>
      
      int func1 (int& a, int& b)
      { // func1
          a = a * 2;
          b = b * 3;
          return a + b;
      } // func1
      
      int main ()
      { // main
          int x = 5, y = 10, z;
      
          z = func1(x, y);
          cout << "x = " << x << ", y = " << y << ", z = " << z << endl;
      } // main
      % g++ -o passbyref passbyref.cpp
      % passbyref
      x = 10, y = 30, z = 40
      
      Answer: x = 10, y = 30, z = 40

    3. % cat passbyconstref.cpp
      #include <iostream.h>
      
      int func1 (const int& a, const int& b)
      { // func1
          a = a * 2;
          b = b * 3;
          return a + b;
      } // func1
      
      int main ()
      { // main
          int x = 5, y = 10, z;
      
          z = func1(x, y);
          cout << "x = " << x << ", y = " << y << ", z = " << z << endl;
      } // main
      % g++ -o passbyconstref passbyconstref.cpp
      passbyconstref.cpp: In function `int func1(const int &, const int &)':
      passbyconstref.cpp:5: assignment of read-only reference `a'
      passbyconstref.cpp:6: assignment of read-only reference `b'
      
      Answer: WON'T COMPILE, because the const keyword in the formal argument list
      (const int& a, const int& b)
      
      indicates that each argument so labeled will not be changed, but in the body of the function the values of the const arguments are changed:
          a = a * 2;
          b = b * 3;
      

    Ask for help with this question.


  2. For this question, you will need to read the document ``The C++ Preprocessor,'' which is available from the CS 2413 webpage:

    http://www.cs.ou.edu/~cs2413/

    Consider the following set of C++ source files:

    1. Give the output of the program if you compile using:

      g++ Point.main.cpp Point.cpp

      Answer:
      % g++ Point.main.cpp Point.cpp
      % a.out
      x = 3, y = 30
      
    2. Give the output of the program if you compile using:

      g++ -DDEBUGGING_VERBOSITY=2 Point.main.cpp Point.cpp

      Answer:
      % g++ -DDEBUGGING_VERBOSITY=2 Point.main.cpp Point.cpp
      % a.out
      Enter Point(1,10)
      Exit  Point(1,10)
      Enter Point(2,20)
      Exit  Point(2,20)
      Point.operator+() called,  b._x = 2, b._y = 20
      Enter Point(3,30)
      Exit  Point(3,30)
      Enter Point.display()
      x = 3, y = 30
      Exit  Point.display()
      ~Point called
      ~Point called
      ~Point called
      

    Ask for help with this question.


  3. For this question, you will need to read the document ``C++ Arrays & Strings,'' which is available from the CS 2413 webpage:

    http://www.cs.ou.edu/~cs2413/

    The Depressingly Dull Corporation (DDC) has many employees. Each employee has:

    Employees come in two kinds, laborers and managers, each of which has an extra piece of information:

    For this question:

    1. Declare a class Employee with the appropriate fields; the fields should have the appropriate level of privacy. The class should also have appropriate methods, including:
      • a default constructor;
      • a constructor that takes values for all of the fields;
      • a copy constructor;
      • a destructor;
      • a display method that outputs all of the employee's data;
      • a method that returns the amount that the employee should be paid this week, given the number of hours that they worked;
      • an output stream function (i.e., a friend).

      Answer:
      #ifndef Employee_h
      #define Employee_h
      
      class Employee {
          friend ostream& operator<< (ostream& s, const Employee& employee);
          protected:
              char*  _first_name;
              char*  _last_name;
              int    _social_security_number;
              double _dollars_per_hour;
              int    _unused_vacation_days;
              int    _unused_sick_days;
          public:
              Employee ();
              Employee (char* first_name, char* last_name,
                        int social_security_number, double dollars_per_hour,
                        int unused_vacation_days, int unused_sick_days);
              Employee (const Employee& source_employee);
              virtual ~Employee ();
              virtual void display ();
              double earnings (double hours_worked);
      }; // class Employee
      
      #endif // #ifndef Employee_h
      


    2. Declare a class Laborer that inherits all of the properties of Employee, but has its own constructors and destructor, as well as a display method that overrides the display method of Employee.

      Answer:
      #ifndef Laborer_h
      #define Laborer_h
      
      #include "Employee.h"
      
      class Laborer : public Employee {
          protected:
              int _part_ID;
          public:
              Laborer ();
              Laborer (char* first_name, char* last_name,
                       int social_security_number, double dollars_per_hour,
                       int unused_vacation_days, int unused_sick_days,
                       int part_ID);
              Laborer (const Laborer& source_laborer);
              virtual ~Laborer ();
              void display ();
      }; // class Laborer
      
      #endif // #ifndef Laborer_h
      


    3. Declare a class Manager that inherits all of the properties of Employee, but has its own constructors and destructor, as well as a display method that overrides the display method of Employee.

      Answer:
      #ifndef Manager_h
      #define Manager_h
      
      #include "Employee.h"
      
      class Manager : public Employee {
          protected:
              int _number_of_papers_shuffled;
          public:
              Manager ();
              Manager (char* first_name, char* last_name,
                       int social_security_number, double dollars_per_hour,
                       int unused_vacation_days, int unused_sick_days,
                       int number_of_papers_shuffled);
              Manager (const Manager& source_manager);
              virtual ~Manager ();
              void display ();
      }; // class Manager
      
      #endif // #ifndef Manager_h
      
    Note: for this question, you do not need to implement the methods of these classes; you only need to declare the classes (i.e., you need to write the Employee.h file, but not the Employee.cpp file).

    Notes About These Answers

    Ask for help with this question.


  4. Implement the following methods from the previous question:

    1. The copy constructors for each of the three classes.
    2. The destructor for the Employee class.
    3. The display methods for each of the three classes.

    Your implementations should not have any redundant code in them; that is, if a method of the Employee class has code to perform a task for its data fields, then the methods for the Laborer and Manager classes should not contain the same code; they should instead invoke the associated method from the Employee class and include code to operate on their subclass-specific fields.

    Answer (see Note below):

    #include <iostream.h>
    #include <string.h>
    #include "Employee.h"
    
    Employee::Employee ()
    { // Employee::Employee
        _first_name             = NULL;
        _last_name              = NULL;
        _social_security_number = 0;
        _dollars_per_hour       = 0.0;
        _unused_vacation_days   = 0;
        _unused_sick_days       = 0;
    } // Employee::Employee
    
    Employee::Employee (char* first_name, char* last_name,
                        int social_security_number, double dollars_per_hour,
                        int unused_vacation_days, int unused_sick_days)
    { // Employee::Employee
        _first_name             = strdup(first_name);
        _last_name              = strdup(last_name);
        _social_security_number = social_security_number;
        _dollars_per_hour       = dollars_per_hour;
        _unused_vacation_days   = unused_vacation_days;
        _unused_sick_days       = unused_sick_days;
    } // Employee::Employee
    
    Employee::Employee (const Employee& source_employee)
    { // Employee::Employee
        _first_name             = strdup(source_employee._first_name);
        _last_name              = strdup(source_employee._last_name);
        _social_security_number = source_employee._social_security_number;
        _dollars_per_hour       = source_employee._dollars_per_hour;
        _unused_vacation_days   = source_employee._unused_vacation_days;
        _unused_sick_days       = source_employee._unused_sick_days;
    } // Employee::Employee
    
    Employee::~Employee ()
    { // Employee::~Employee
        if (_last_name  != NULL) delete[] _last_name;
        if (_first_name != NULL) delete[] _first_name;
    } // Employee::~Employee
    
    void Employee::display ()
    { // Employee::display
        cout << "Name:  " << _last_name << ", " << _first_name << endl;
        cout << "SS#:   " << _social_security_number << endl;
        cout << "Pay Rate:  $" << _dollars_per_hour << " per hour" << endl;
        cout << "Unused Vacation Days:  " << _unused_vacation_days << endl;
        cout << "Unused Sick Days:      " << _unused_sick_days << endl;
    } // Employee::display
    
    double Employee::earnings (double hours_worked)
    { // Employee::earnings
        return hours_worked * _dollars_per_hour;
    } // Employee::earnings
    
    ostream& operator<< (ostream& s, const Employee& employee)
    { // operator<<
        s << employee._last_name << ", " <<
             employee._first_name <<
             " (" << employee._social_security_number << "): $" <<
             employee._dollars_per_hour << "/hour, " <<
             employee._unused_vacation_days << " vacation days, " <<
             employee._unused_sick_days     << " sick days";
    } // operator<<
    



    #include <iostream.h>
    #include "Laborer.h"
    
    Laborer::Laborer ()
    { // Laborer::Laborer
        _part_ID = 0;
    } // Laborer::Laborer
    
    Laborer::Laborer (char* first_name, char* last_name,
                      int social_security_number, double dollars_per_hour,
                      int unused_vacation_days, int unused_sick_days,
                      int part_ID)
        : Employee (first_name, last_name, social_security_number,
                    dollars_per_hour, unused_vacation_days, unused_sick_days)
    { // Laborer::Laborer
        _part_ID = part_ID;
    } // Laborer::Laborer
    
    Laborer::Laborer (const Laborer& source_laborer)
        : Employee (source_laborer)
    { // Laborer::Laborer
        _part_ID = source_laborer._part_ID;
    } // Laborer::Laborer
    
    Laborer::~Laborer ()
    { // Laborer::~Laborer
    } // Laborer::~Laborer
    
    void Laborer::display ()
    { // Laborer::display
        Employee::display();
        cout << "Part ID:               " << _part_ID << endl;
    } // Laborer::display
    



    #include <iostream.h>
    #include "Manager.h"
    
    Manager::Manager ()
    { // Manager::Manager
        _number_of_papers_shuffled = 0;
    } // Manager::Manager
    
    Manager::Manager (char* first_name, char* last_name,
                      int social_security_number, double dollars_per_hour,
                      int unused_vacation_days, int unused_sick_days,
                      int number_of_papers_shuffled)
        : Employee (first_name, last_name, social_security_number,
                    dollars_per_hour, unused_vacation_days, unused_sick_days)
    { // Manager::Manager
        _number_of_papers_shuffled = number_of_papers_shuffled;
    } // Manager::Manager
    
    Manager::Manager (const Manager& source_manager)
        : Employee (source_manager)
    { // Manager::Manager
        _number_of_papers_shuffled = source_manager._number_of_papers_shuffled;
    } // Manager::Manager
    
    Manager::~Manager ()
    { // Manager::~Manager
    } // Manager::~Manager
    
    void Manager::display ()
    { // Manager::display
        Employee::display();
        cout << "Number of papers shuffled: " << _number_of_papers_shuffled <<
            endl;
    } // Manager::display
    

    Note: this answer includes definition for all of the methods of each class, but the question asked for only a subset of the methods. You are responsible only for the subset asked for.

    And here's proof that the above solution works:

    % cat Employee.main.cpp
    #include <iostream.h>
    #include "Employee.h"
    
    int main ()
    { // main
        Employee default_employee;
        Employee full_employee("Henry", "Neeman", 123456789, 18.75, 22, 19);
        Employee copy_employee = full_employee;
    
        cout << "Default employee:" << endl;
        default_employee.display();
        cout << endl;
        cout << "Full employee:" << endl;
        cout << full_employee << endl;
        cout << endl;
        cout << "Copy employee:" << endl;
        cout << copy_employee << endl;
    } // main
    % g++ Employee.main.cpp Employee.cpp
    % a.out
    Default employee:
    Name:  (null), (null)
    SS#:   0
    Pay Rate:  $0 per hour
    Unused Vacation Days:  0
    Unused Sick Days:      0
    
    Full employee:
    Neeman, Henry (123456789): $18.75/hour, 22 vacation days, 19 sick days
    
    Copy employee:
    Neeman, Henry (123456789): $18.75/hour, 22 vacation days, 19 sick days
    



    % cat Laborer.main.cpp
    #include <iostream.h>
    #include "Laborer.h"
    
    int main ()
    { // main
        Laborer default_laborer;
        Laborer full_laborer("Henry", "Neeman", 123456789, 18.75, 22, 19, 98765);
        Laborer copy_laborer = full_laborer;
    
        cout << "Default laborer:" << endl;
        default_laborer.display();
        cout << endl;
        cout << "Full laborer:" << endl;
        full_laborer.display();
        cout << endl;
        cout << "Copy laborer:" << endl;
        copy_laborer.display();
    } // main
    % g++ Laborer.main.cpp Laborer.cpp Employee.cpp
    % a.out
    Default laborer:
    Name:  (null), (null)
    SS#:   0
    Pay Rate:  $0 per hour
    Unused Vacation Days:  0
    Unused Sick Days:      0
    Part ID:               0
    
    Full laborer:
    Name:  Neeman, Henry
    SS#:   123456789
    Pay Rate:  $18.75 per hour
    Unused Vacation Days:  22
    Unused Sick Days:      19
    Part ID:               98765
    
    Copy laborer:
    Name:  Neeman, Henry
    SS#:   123456789
    Pay Rate:  $18.75 per hour
    Unused Vacation Days:  22
    Unused Sick Days:      19
    Part ID:               98765
    



    % cat Manager.main.cpp
    #include <iostream.h>
    #include "Manager.h"
    
    int main ()
    { // main
        Manager default_manager;
        Manager full_manager("Henry", "Neeman", 123456789, 18.75, 22, 19, 136);
        Manager copy_manager = full_manager;
    
        cout << "Default manager:" << endl;
        default_manager.display();
        cout << endl;
        cout << "Full manager:" << endl;
        full_manager.display();
        cout << endl;
        cout << "Copy manager:" << endl;
        copy_manager.display();
    } // main
    % g++ Manager.main.cpp Manager.cpp Employee.cpp
    % a.out
    Default manager:
    Name:  (null), (null)
    SS#:   0
    Pay Rate:  $0 per hour
    Unused Vacation Days:  0
    Unused Sick Days:      0
    Number of papers shuffled: 0
    
    Full manager:
    Name:  Neeman, Henry
    SS#:   123456789
    Pay Rate:  $18.75 per hour
    Unused Vacation Days:  22
    Unused Sick Days:      19
    Number of papers shuffled: 136
    
    Copy manager:
    Name:  Neeman, Henry
    SS#:   123456789
    Pay Rate:  $18.75 per hour
    Unused Vacation Days:  22
    Unused Sick Days:      19
    Number of papers shuffled: 136
    



    Ask for help with this question.