Programming Projects

Programming Projects require more problem-solving than Practice Programs and can usually be solved many different ways. Visit www.myprogramminglab.com to complete many of these Programming Projects online and get instant feedback.

  1. Give the definition of a class named Doctor whose objects are records for a clinic’s doctors. This class will be a derived class of the class SalariedEmployee given in Display 15.5. A Doctor record has the doctor’s specialty (such as “Pediatrician,” “Obstetrician,” “General Practitioner,” etc., so use type string) and office visit fee (use type double). Be sure your class has a reasonable complement of constructors, accessor, and mutator member functions, an overloaded assignment operator, and a copy constructor. Write a driver program to test all your functions.

  2. Create a base class called Vehicle that has the manufacturer’s name (type string), number of cylinders in the engine (type int), and owner (type Person, given below). Then create a class called Truck that is derived from Vehicle and has additional properties: the load capacity in tons (type double since it may contain a fractional part) and towing capacity in pounds (type int). Be sure your classes have a reasonable complement of constructors, accessor, and mutator member functions, an overloaded assignment operator, and a copy constructor. Write a driver program that tests all your member functions.

    The definition of the class Person follows. The implementation of the class is part of this Programming Project.

    class Person
    {
    public:
        Person();
        Person(string theName);
        Person(const Person& theObject);
        string getName() const;
        Person& operator = (const Person& rtSide);
        friend istream& operator >>(istream& inStream,
                       Person& personObject); 
       friend ostream& operator <<(ostream& outStream,
                       const Person& personObject);
    private:
        string name;
    };
  3. Define a Car class that is derived from the Vehicle class given in Programming Project 2. Define a class called SportsCar that is derived from Car class. Be creative in choosing member variables and functions. Write a driver program to test the Car and SportsCar classes. (No pun intended.)

  4. Give the definition of two classes, Patient and Billing, whose objects are records for a clinic. Patient will be derived from the class Person given in Programming Project 2. A Patient record has the patient’s name (inherited from the class Person) and primary physician, of type Doctor defined in Programming Project 2. A Billing object will contain a Patient object, a Doctor object, and an amount due of type double. Be sure your classes have a reasonable complement of constructors, accessor, and mutator member functions, an overloaded assignment operator, and a copy constructor. First write a driver program to test all your member functions, and then write a test program that creates at least two patients, at least two doctors, and at least two Billing records, then prints out the total income from the Billing records.

  5. Consider a graphics system that has classes for various figures—rectangles, squares, triangles, circles, and so on. For example, a rectangle might have data members for height, width, and center point, while a square and circle might have only a center point and an edge length or radius, respectively. In a well-designed system, these would be derived from a common class, Figure. You are to implement such a system.

    The class Figure is the base class. You should add only Rectangle and Triangle classes derived from Figure. Each class has stubs for member functions erase and draw. Each of these member functions outputs a message telling what function has been called and what the class of the calling object is. Since these are just stubs, they do nothing more than output this message. The member function center calls the erase and draw functions to erase and redraw the figure at the center. Since you have only stubs for erase and draw, center will not do any “centering” but will call the member functions erase and draw. Also add an output message in the member function center that announces that center is being called. The member functions should take no arguments.

    There are three parts to this project:

    1. Write the class definitions using no virtual functions. Compile and test.

    2. Make the base class member functions virtual. Compile and test.

    3. Explain the difference in results.

    For a real example, you would have to replace the definition of each of these member functions with code to do the actual drawing. You will be asked to do this in Programming Project 6.

    Use the following main function for all testing:

    //This program tests Programming Project 5. #include <iostream>
    #include "figure.h"
    #include "rectangle.h"
    #include "triangle.h"
    using std::cout;
    
    int main( )
    {
        Triangle tri;
        tri.draw( );
        cout <<
          "\nDerived class Triangle object calling center( ).\n";
        tri.center( ); //Calls draw and center
        Rectangle rect;
        rect.draw( );
        cout <<
          "\nDerived class Rectangle object calling center().\n";
        rect.center( ); //Calls draw and center
        return 0;
    }
  6. Flesh out Programming Project 5. Give new definitions for the various constructors and the member functions Figure::center, Figure::draw, Figure::erase, Triangle::draw, Triangle::erase, Rectangle::draw, and Rectangle::erase so that the draw functions actually draw figures on the screen by placing the character '*' at suitable locations. For the erase functions, you can simply clear the screen (by outputting blank lines or by doing something more sophisticated). There are a lot of details in this problem, and you will have to make decisions about some of them on your own.

  7. Banks have many different types of accounts, often with different rules for fees associated with transactions such as withdrawals. Customers are allowed to transfer funds between accounts incurring the appropriate fees associated with withdrawal of funds from one account.

    Write a program with a base class for a bank account and two derived classes (as described below) representing accounts with different rules for withdrawing funds. Also write a function that transfers funds from one account (of any type) to another. A transfer is a withdrawal from one account and a deposit into the other. Since the transfer can be done at any time with any type of account, the withdraw function in the classes must be virtual. Write a main program that creates three accounts (one from each class) and tests the transfer function.

    For the classes, create a base class called BankAccount that has the name of the owner of the account (a string) and the balance in the account (double) as data members. Include member functions deposit and withdraw (each with a double for the amount as an argument) and accessor functions getName and getBalance. Deposit will add the amount to the balance (assuming the amount is nonnegative) and withdraw will subtract the amount from the balance (assuming the amount is nonnegative and less than or equal to the balance). Also create a class called MoneyMarketAccount that is derived from BankAccount. In a MoneyMarketAccount the user gets two free withdrawals in a given period of time (don’t worry about the time for this problem). After the free withdrawals have been used, a withdrawal fee of $1.50 is deducted from the balance per withdrawal. Hence, the class must have a data member to keep track of the number of withdrawals. It also must override the withdraw definition. Finally, create a CDAccount class (to model a Certificate of Deposit) derived from BankAccount that in addition to having the name and balance also has an interest rate. CDs incur penalties for early withdrawal of funds. Assume that a withdrawal of funds (any amount) incurs a penalty of 25% of the annual interest earned on the account. Assume the amount withdrawn plus the penalty are deducted from the account balance. Again, the withdraw function must override the one in the base class. For all three classes, the withdraw function should return an integer indicating the status (either ok or insufficient funds for the withdrawal to take place). For the purposes of this exercise, do not worry about other functions and properties of these accounts (such as when and how interest is paid).

  8. Radio Frequency IDentification (RFID) chips are small tags that can be placed on a product. They behave like wireless barcodes and can wirelessly broadcast an identification number to a receiver. One application of RFID chips is to use them to aid in the logistics of shipping freight. Consider a shipping container full of items. Without RFID chips, a human has to manually inventory all of the items in the container to verify the contents. With an RFID chip attached to the shipping container, the RFID chip can electronically broadcast to a human the exact contents of the shipping container without human intervention.

    To model this application, write a base class called ShippingContainer that has a container ID number as an integer. Include member functions to set and access the ID number. Add a virtual function called getManifest that returns an empty string. The purpose of this function is to return the contents of the shipping container.

    Create a derived class called ManualShippingContainer that represents the manual method of inventorying the container. In this method, a human simply attaches a textual description of all contents of the container. For example, the description might be “4 crates of apples. 10 crates of pears.” Add a new class variable of type string to store the manifest. Add a function called setManifest that sets this string. Override the getManifest function so that it returns this string.

    Create a second derived class called RFIDShippingContainer that represents the RFID method of inventorying the container. To simulate what the RFID chips would compute, create an add function to simulate adding an item to the container. The class should store a list of all added items (as a string) and their quantity using the data structures of your choice. For example, if the add function were invoked three times as follows:

    rfidContainer.add("crate of pears"); // Add one crate of pears
    rfidContainer.add("crate of apples"); // Add one crate of apples
    rfidContainer.add("crate of pears"); // Add one crate of pears

    At this point, the data structure should be storing a list of two items: crate of apples and crate of pears. The quantity of apples is 1and the quantity of pears is 2. Override the getManifest function so that it returns a string of all items that is built by traversing the list of items. In the example above, the return string would be “2 crate of pears. 1 crate of apples.

    Finally, write a main program that creates an array of pointers to six ShippingContainer objects. Instantiate the array with three Manual-ShippingContainer objects and three RFIDShippingContainer objects. For the ManualShippingContainer objects, you will have to invoke setManifest to set the contents. For the RFIDShippingContainer objects, you will have to invoke add to set the contents (although, if this were real, the contents of the container would “add” themselves via the RFID chips instead of requiring a human to type them in). Finally, write a loop that iterates through all ShippingContainer pointers and outputs each object’s manifest along with the shipping container ID. This is the output that the receiver of the shipping containers would like to see.

    You may need to convert an integer into a string. A simple way to do this in C++11 is: string s = to_string(intVariable);

  9. The goal for this Programming Project is to create a simple two-dimensional predator–prey simulation. In this simulation the prey are ants and the predators are doodlebugs. These critters live in a world composed of a 20 × 20 grid of cells. Only one critter may occupy a cell at a time. The grid is enclosed, so a critter is not allowed to move off the edges of the world. Time is simulated in time steps. Each critter performs some action every time step.

    The ants behave according to the following model:

    • Move. Every time step, randomly try to move up, down, left, or right. If the neighboring cell in the selected direction is occupied or would move the ant off the grid, then the ant stays in the current cell.

    • Breed. If an ant survives for three time steps, then at the end of the time step (that is, after moving) the ant will breed. This is simulated by creating a new ant in an adjacent (up, down, left, or right) cell that is empty. If there is no empty cell available, then no breeding occurs. Once an offspring is produced, an ant cannot produce an offspring until three more time steps have elapsed.

    The doodlebugs behave according to the following model:

    • Move. Every time step, if there is an adjacent ant (up, down, left, or right), then the doodlebug will move to that cell and eat the ant. Otherwise, the doodlebug moves according to the same rules as the ant. Note that a doodlebug cannot eat other doodlebugs.

    • Breed. If a doodlebug survives for eight time steps, then at the end of the time step it will spawn off a new doodlebug in the same manner as the ant.

    • Starve. If a doodlebug has not eaten an ant within the last three time steps, then at the end of the third time step it will starve and die. The doodlebug should then be removed from the grid of cells.

    During one turn, all the doodlebugs should move before the ants do.

    Write a program to implement this simulation and draw the world using ASCII characters of “o“ for an ant and “X“ for a doodlebug. Create a class named Organism that encapsulates basic data common to both ants and doodlebugs. This class should have a virtual function named move that is defined in the derived classes of Ant and Doodlebug. You may need additional data structures to keep track of which critters have moved.

    Initialize the world with 5 doodlebugs and 100 ants. After each time step, prompt the user to press Enter to move to the next time step. You should see a cyclical pattern between the population of predators and prey, although random perturbations may lead to the elimination of one or both species.

  10. Listed below is code to play a guessing game. In the game two players attempt to guess a number. Your task is to extend the program with objects that represent either a human player or a computer player. The rand() function requires you include cstdlib (see Appendix 4):

    bool checkForWin(int guess, int answer)
    {
        cout<< "You guessed" << guess << ".";
        if (answer == guess)
        {
            cout<< "You're right! You win!" <<endl;
            return true;
        }
        else if (answer < guess)
                cout<< "Your guess is too high." <<endl;
        else
                cout<< "Your guess is too low." <<endl;
        return false;
    }
    void play(Player &player1, Player &player2)
    {
        int answer = 0, guess = 0;
        answer = rand() % 100;
        bool win = false;
        while (!win)
        {
            cout<< "Player 1's turn to guess." <<endl;
            guess = player1.getGuess();
            win = checkForWin(guess, answer);
            if (win) return;
            cout<< "Player 2's turn to guess." <<endl;
            guess = player2.getGuess();
            win = checkForWin(guess, answer);
        }
    }

    The play function takes as input two Player objects. Define the Player class with a virtual function named getGuess(). The implementation of Player::getGuess() can simply return 0. Next, define a class named HumanPlayer derived from Player. The implementation of HumanPlayer::getGuess() should prompt the user to enter a number and return the value entered from the keyboard. Next, define a class named ComputerPlayer derived from Player. The implementation of ComputerPlayer::getGuess() should randomly select a number between 0 and 99 (see Appendix 4 for information on random number generation). Finally, construct a main function that invokes play(Player &player1, Player &player2) with two instances of a HumanPlayer (human versus human), an instance of a HumanPlayer and ComputerPlayer (human versus computer), and two instances of ComputerPlayer (computer versus computer).

  11. The computer player in Programming Project 10 does not play very well in the number guessing game, since it only makes random guesses. Modify the program so that the computer plays a more informed game. The specific strategy is up to you, but you must add function(s) to the Player and ComputerPlayer classes so that the play(Player& player1, Player &player2) function can send the results of a guess back to the computer player. In other words, the computer must be told if its last guess was too high or too low, and it also must be told if its opponent’s last guess was too high or too low. The computer then can use this information to revise its next guess. Also, add any necessary functions to allow the computer player to play multiple consecutive games.

  12. Start with the definition of the Queue class given in Section 13.2 and modify it to store integers instead of characters. A special type of queue is a priority queue. A priority queue behaves like a regular queue except the remove function always extracts the item with the smallest value (this is the item with the highest priority). Create a PriorityQueue class that is derived from the Queue class with appropriate constructors. Redefine the remove function in the PriorityQueue class to extract the item with the smallest value. Test the PriorityQueue class by adding several numbers to a PriorityQueue object, then remove each one, printing the removed numbers as they are removed from the queue.

  13. The following is an attempt to create a class to represent information about pets:

    class Pet
    {
    public:
           Pet();
           void printDescription();
    
           string name;
           int type;
           bool neuterSpayed;
           bool talks;
    };
    Pet::Pet() : type(0), neuterSpayed(false),
                 talks(false)
    { }
    void Pet::printDescription()
    {
           switch (type)
           {
             case 0:
              cout << "Dog named " << name << endl;
              cout << "Neuter/Spayed: " <<
                      neuterSpayed;
              break;
            case 1:
              cout << "Cat named " << name << endl;
              cout << "Neuter/Spayed: " <<
                      neuterSpayed;
              break;
            case 2:
              cout << "Bird named " << name << endl;
              cout << "Talks: " << talks << endl;
              break;
           }
             cout << endl;
    }
    

    Rewrite this code using inheritance. You should have a Pet class with subclasses for Dog, Cat, and Bird. Variables should be associated with the appropriate classes, defined as private when appropriate, and have appropriate functions to access the variables. Rewrite the printDescription function as a virtual function. There should no longer be the need for a switch statement or a type variable.

    Write a main function that creates a vector or array of pets that includes at least one bird, one dog, and one cat, and then loops through and outputs a description of each one.