COMP 2012 Object-Oriented Programming and Data Structures

Lab 2 Class Construction and Destruction

Design a Event Booking System

There will be a lot of events coming for the HKUST 30 Anniversary! In this lab, you are going to design an event booking system for visitors to register some events. To do that, we need to utilize Constructor and Destructor. Key points include:

  • Type conversion constructor
  • Copy constructor
  • Other constructors (e.g., Delegating constructor)
  • Destructor

As a prototype, the system should be capable of managing resources (i.e., tickets and events) and providing a booking service. When a person makes a booking, he will reserve an event as well as a ticket. As there are only maxNumTicket tickets and maxNumEvent events, the system would reject invalid bookings that exceed the maximum capacity.

Are You Ready?! Download the skeleton source file and get started!!!

Overview

There are 4 classes: Ticket, Event, Person, and BookingSystem. The first three classes, Ticket, Event and Person, are already implemented for you. Therefore, you only need to implement the BookingSystem class. Specifically, you should only add code to the TODOs parts in bookingsystem.cpp, otherwise it may fail the automatic grading. The following code shows the definition of the 4 classes:

  1. The Ticket class (in event-ticket.h):
    class Ticket
    {
    private:
        int ticketID;
    public:
        Ticket(int id);               // Conversion constructor
        Ticket(const Ticket &other);  // Copy constructor
        ~Ticket();                    // Destructor
    };
    
    
  2. The Event class (in event-ticket.h):
    class Event
    {
    private:
        int eventID;
    public:
        Event(int id);                // Conversion constructor
        Event(const Event &other);    // Copy constructor
        ~Event();                     // Destructor
    };
    
    
  3. The Person class (in person.h):
    class Person
    {
    public:
        char *name;
        Event *event;
        Ticket *ticket;
    
        Person(const char *name, Event *event, Ticket *ticket);     // General constructor.
        Person(const Person &other);                                // Copy constructor, deep copy name only.
        Person(const Person &other, Event *event, Ticket *ticket);  // Delegating constructor
        ~Person();                                                  // Destructor
    
        Event* DropEvent();
        Ticket* DropTicket();
    };
    
  4. The BookingSystem class (in bookingsystem.h):
    const int maxNumEvent = 3;   // Maximum number of Event.
    const int maxNumTicket = 3;  // Maximum number of Ticket.
    const int maxNumPerson = 3;  // Maximum number of Person.
    
    class BookingSystem
    {
    private:
        Event *events[maxNumEvent];
        Ticket *tickets[maxNumTicket];
        Person *persons[maxNumPerson];
    
        int numEvent;      // Current number of Event.
        int numTicket;     // Current number of Ticket.
        int numPerson;     // Current number of Person.
        int SN;            // Serial number
    
        int findIndexByName(const char* name);
    
    public:
        // TODO: General constructor
        BookingSystem(int id, int nEvent, int nTicket);
        // TODO: Copy constructor
        BookingSystem(const BookingSystem &other);
        // TODO: Delegating constructor
        BookingSystem(int id, int capacity);
        // TODO: Delegating constructor
        BookingSystem(int id, const BookingSystem &other);
        // TODO: Destructor
        ~BookingSystem();
    
        void releaseEvent(const char* name);
        void releaseTicket(const char* name);
    
        // TODO: accept person's booking by allocating a Person object.
        // The person would like to reserve an event with a ticket.
        void makeBooking(const char* name);
    
        // print the log
        void log() const;
    };
    
We have listed all testing cases in the main.cpp file. The testing operations include:
  1. Initialize a booking system.
  2. Two people come and reserve tickets for two events.
  3. One person unregisters an event but holds the ticket, and someone else makes a booking again.
  4. One person unregisters an event and returns the ticket.
  5. Time to back up your system! Copy the original system, including all tickets, events and persons.
  6. End of the registration. Destroy the booking system.
  7. Find a ticket left. Create a new booking system for one person with one ticket of one event.
  8. End of all events. Clear all existing data.

Lab tasks

  1. Before you start, we recommend you read the provided codes and understand the overall framework. The recommended reading order is:
    • event-ticket.h and event-ticket.cpp
    • person.h and person.cpp
    • bookingsystem.h and bookingsystem.cpp
    • main.cpp
  2. Finish the TODOs in bookingsystem.cpp.
    • Complete the general constructor of the BookingSystem class. Allocate memory for events, tickets and persons and initalize all member variables
    • Complete the copy constructor of the BookingSystem class. Deep copy all data members of another booking system. Noted that we need to do more when copying Person class!
    • Complete the delegating constructor of the BookingSystem class. Note for this part, you should only add one extra line of code.
    • Complete the delegating constructor for the copy function of the BookingSystem class. Deep copy all data members of another restaurant with a new ID.
    • Complete the destructor of the BookingSystem class. Note that we need to do more when dealing with Person class.
    • Complete the BookingSystem::makeBooking. One person will consume one ticket and one event. The booking system will give the ownership of the latest event and ticket objects to the Person.
  3. Run the Makefile by make to build the executable (i.e., lab2.exe).
  4. Run lab2.exe to check with the expected output below:
  5. 1. Initialize booking system!
    Event with ID 1 Constructed!
    Event with ID 2 Constructed!
    Event with ID 3 Constructed!
    Ticket with ID 1 Constructed!
    Ticket with ID 2 Constructed!
    Ticket with ID 3 Constructed!
    #0 BookingSystem Constructed!
    ----------------------
    | Booking System Log |
    ----------------------
    #0 booking system has...
    Event: 3/3
    Ticket: 3/3
    Person: 0/3
    2. Two people come and reserve tickets for two events.
    Record of John Constructed!
    Booking is successful!!!
    Record of Emma Constructed!
    Booking is successful!!!
    ----------------------
    | Booking System Log |
    ----------------------
    #0 booking system has...
    Event: 1/3
    Ticket: 1/3
    Person: 2/3
    3. One person unregister an event but hold the ticket, and someone else make a booking again.
    Emma dropped an event.
    Record of Peter Constructed!
    Booking is successful!!!
    ----------------------
    | Booking System Log |
    ----------------------
    #0 booking system has...
    Event: 1/3
    Ticket: 0/3
    Person: 3/3
    4. One person unregister an event and return the ticket.
    Peter dropped an event.
    Peter dropped a ticket.
    ----------------------
    | Booking System Log |
    ----------------------
    #0 booking system has...
    Event: 2/3
    Ticket: 1/3
    Person: 3/3
    5. It is a good behavior to back up your data.
    Event with ID 1 Copied!
    Event with ID 2 Copied!
    Ticket with ID 1 Copied!
    Event with ID 3 Copied!
    Ticket with ID 3 Copied!
    Record of John Copied!
    Record of John with event and ticket Copied!
    Ticket with ID 2 Copied!
    Record of Emma Copied!
    Record of Emma with event and ticket Copied!
    Record of Peter Copied!
    Record of Peter with event and ticket Copied!
    #0 BookingSystem is Copied as #1 BookingSystem!
    ----------------------
    | Booking System Log |
    ----------------------
    #1 booking system has...
    Event: 2/3
    Ticket: 1/3
    Person: 3/3
    6. End of the registration. Destroy the booking system.
    Event with ID 1 Destructed!
    Event with ID 2 Destructed!
    Ticket with ID 1 Destructed!
    Event with ID 3 Destructed!
    Ticket with ID 3 Destructed!
    Record of John Destructed.
    Ticket with ID 2 Destructed!
    Record of Emma Destructed.
    Record of Peter Destructed.
    #1 BookingSystem is Destructed.
    Event with ID 1 Destructed!
    Event with ID 2 Destructed!
    Ticket with ID 1 Destructed!
    Event with ID 3 Destructed!
    Ticket with ID 3 Destructed!
    Record of John Destructed.
    Ticket with ID 2 Destructed!
    Record of Emma Destructed.
    Record of Peter Destructed.
    #0 BookingSystem is Destructed.
    7. Find a ticket left. Create a new booking system for one person with one ticket of one event.
    Event with ID 1 Constructed!
    Ticket with ID 1 Constructed!
    #2 BookingSystem Constructed!
    By using the Delegating constructor!
    ----------------------
    | Booking System Log |
    ----------------------
    #2 booking system has...
    Event: 1/3
    Ticket: 1/3
    Person: 0/3
    Record of Mary Constructed!
    Booking is successful!!!
    ----------------------
    | Booking System Log |
    ----------------------
    #2 booking system has...
    Event: 0/3
    Ticket: 0/3
    Person: 1/3
    8. End of all events. Clear all existing data.
    Event with ID 1 Destructed!
    Ticket with ID 1 Destructed!
    Record of Mary Destructed.
    #2 BookingSystem is Destructed.
    

Hint

  1. Reading every file in the source folder will help you understand what is going on.
  2. If you cannot get the same output, check if you have properly constructed and destructed the objects. Are there any memory leaks?

Extra: Assert

  1. You might notice that in the bookingsystem.cpp, we have added assert(...). An assert is used to evaluate some assumptions in the program. For example, in some point of the program, we think that the number of people should be equal to 2, otherwise there should be some bug in the program. Then we can add assert(numOfPeople == 2); to that specific position. If it is correct, then nothing happened. However, when it is wrong, the program will be aborted and output the error on the standart error output. Adding asserts in the code could help us debug the program.
  2. By default, the assert only receive the condition as the only one parameter, if we want to add some customized messages (e.g., some assumptions), we can "hack" the assert with some tricks. To include custom message, we can write assert(numOfPeople == 2 && "There should be two people here!"). That is, the condition to check && an error message. Why it works? First, the error message, which is a literal C string, is of the type const char*, meaning that it is pointer which is always not nullptr. Thus, the second condition is always true. We can append the condition without affecting the original condition. It is because true && true is true and false && true is false. Finally, when the our code is wrong and assert out the condition in the terminal, we can see our message: numOfPeople == 2 && "There should be two people here!". This is useful to remind us the assumption we have made. More details please check the following discussion.

Submission Deadline and Guidelines:

The due date and time will be 10-min after your lab session. You are supposed to upload the following files in an archive to ZINC:

- bookingsystem.cpp
You can submit your codes multiple times by the deadline. Only the last submission will be graded.
Page maintained by
  • Wai TONG
  • Last Modified:
Homepage