Assessment 3 Question 1 The following UML diagram specifies a number of classes that model employees and different kinds of payments: Every employee has an ID, a first name and surname, and a means of payment. A salaried employee is paid a salary once a month. An hourly paid employee is paid an amount calculated once a month from the number of hours worked. Whenever the employee works, the number of hours can be incremented. The amount paid is simply the total number of hours multiplied by the hourly rate. Someone employed on a commission basis is paid a commission once a month calculated from the total of all the sales they made in the month. Whenever a sale is made, the total sales can be increased. The amount paid is simply the commission rate multiplied by the total sales. Implement the five classes Employee, Payment, Salary, Hourly and Commission. Note the following: • These classes must each have their definitions and implementations in separate header and source files. • The Employee class should allocate unique IDs to each new Employee instance, starting with the number 1001. The static data member nextID should therefore be initialised appropriately, assigned to the id of each new instance, and incremented accordingly. • Since Employee instances each contain a Payment and access it by means of a pointer, the Employee class needs to implement a copy constructor (to do a deep copy) and a destructor to deallocate the memory of the Payment. • The Payment class has an abstract member function pay() that must be implemented by each of its (concrete) subclasses to calculate the monthly payment as described above. • The type data member of the Payment class is protected to allow it to be initialised by the constructors of the Salary, Hourly and Commission classes. • You can assume that the system using these classes will call the addHours() and addSales() member functions on relevant instances of hourly and commission payments of employees as required (see below.) Implement another class called EmployeeList according to the following UML diagram: Note that the member functions and data members of the QList and Employee classes are not provided in this diagram. They are as provided in the QList definition in the Qt class reference, and as in the UML diagram at the beginning of this question, respectively. Note the following about the EmployeeList class: • EmployeeList inherits from the class template QList, but is not templatized itself. All its elements are Employees. • EmployeeList inherits all the member functions of QList, so it need not implement any of its own. Write a program (a console application) to test the member functions of the Employee class and the Payment subclasses. It should do the following: • Add at least six employees (including at least two of each of the concrete subclasses of Payment) to an EmployeeList. • Call the addHours() member function on the Hourly payment of at least one instance of an hourly paid employee that has been stored in the list. • Call the addSales() member functions on the Commission payment of at least one instance of a commission paid employee in the list. • Display a report of the payments owed to each employee at the end of the month, grouped into salaried, hourly paid and commission paid employees. Question 2 Implement the class Gate class to represent a restricted entrance as depicted in the UML diagram below: The function checkPassword() returns true if p is equal to password or false otherwise. Write a Graphical User Interface (GUI) application to simulate an access control pin pad found at the entrance using the Gate as the model class. The user should be provided with a description of a gate and a facility to enter a password followed by a #. The application should verify the password and display an appropriate message (access granted or denied) to the user. Given below is the GUI expected from your application: Note that you are expected to program the GUI manually without using Qt Designer. Even though the class can be used for multiple gates with different descriptions and passwords, you only need to test the class with one Gate object. Question 3 Consider the following UML diagram: The Customer class is as defined follows: The operations of the CustomerList class are intended to do the following: • add() should append a customer to the list. However, it must first check whether the ID of the customer is unique by searching for it in the customers already in the list. If another customer has the same ID, the operation should return false and terminate without adding the new customer. Otherwise it should append the customer to the end of the list and return true. • remove() should remove a customer from the list. If the customer is not present, the operation should return false, otherwise it should remove the customer and return true. • findByID() should return a customer that has the provided ID. If the list contains no customer with that ID, the operation should return the null pointer. • findByName() should return a list of customers that have the provided name. If no customers have that name, it should return an empty list. • findByDPC() should return a list of customers that have the provided postal code in their delivery address. If no customers have that code, it should return an empty list. As specified in the diagram, the CustomerList class must inherit from QList. To implement its member functions, one could search through the QList using a linear search, but this would be very inefficient. A better way would be to maintain a number of indices in the form of an associative container (like a QMap, QHash, QMultiMap or QMultiHash) to provide fast lookups. In particular: COS2614 • Use an associative container to store pointers to Customers with their IDs as keys, to allow a customer with a particular ID to be found quickly. • Use an associative container to store pointers to Customers with their names as keys, to allow customers with a particular name to be found quickly. • Use an associative container to store pointers to Customers with the postal codes of their delivery addresses as keys, to allow customers with a particular code to be found quickly. Note that the pointers in these associative containers should point to the existing Customers in the QList, not to copies of the Customers. These containers should be defined as private data members of the CustomerList class. Then the member functions of CustomerList should do the following: • findByID(), findByName() and findByDPC() should use the relevant indexing container to find and extract the required information. • add() should use findByID() to check whether the ID is unique. If so, it must append the customer to the list and also update the three indexing containers. • remove() should find and remove a specified customer. It also needs to update the three indexing containers, and deallocate the memory used for the customer. Write a console application to test all these functions. The program should add at least 10 customers to a list and then generate and display the result of searching for customers with a particular ID, a particular name and a particular postal code entered from the keyboard. We have provided the definition and implementation of a RandomCustomerFactory class in the Additional Resources folder for COS2614, which will generate random Customers that can be stored in the CustomerList. (This will save you - and us from having to type in the details of 10 customers to be stored in the list when testing your program.) You should use this class as part of your project.