Object-oriented design and programming
Learning outcomes
The purpose of this assignment is to target the following learning outcomes:
? Gain confidence modeling a problem.
? Gain confidence programming in C++.
? Apply OOP concepts such as inheritance and encapsulation.
? Apply good coding practices such as naming conventions and code reuse.
1 The Emergency Services System
In this assignment you will simulate the management of an emergency services system. Your program will allow
an emergency services system to manage emergencies by providing functionality to represent users of the system
(staff, civilians), represent emergencies, represent vehicles, assign staff to emergencies, etc. You have been given
headers with class and method declarations for the classes you must implement in parts of this assignment. You
are encouraged to add helper methods or data members to these classes where necessary to structure and simplify
code, but you should not change any existing method declarations (except where specified).
2 Tasks
2.1 Private copy constructors and copy-assignment operators
You will notice in most of the classes we have declared the copy constructors and copy-assignment constructors as
private. This means you are not allowed to pass these types around by value (review the lecture about copying
objects). Instead, you must use pointers to those types. While the declarations are provided inside the respective
header files, you only need to provide simple implementations in the corresponding files to stop compiler warnings
(if any).
2.2 Implement the Vehicle and Address classes [Task 1]
You will need to complete the implementation of the following classes: Vehicle and Address classes. The very first
test only requires you to return your username (formerly known as UPI) inside EmergencyServicesSystem::author().
2.2.1 Implement the Vehicle class
You may add more code to the header, but don’t change the existing method declarations. The Vehicle class holds
the properties of a vehicle which will transport staff to an emergency. Every vehicle has a name and a capacity that
determines how many staff it can transport. You need to declare member variables and implement the constructor,
getName() and getCapacity() methods.
1
? Vehicle(const string &name,int capacity)
Implement the constructor of the Vehicle class. The parameters passed into this constructor refer to the name
and capacity of the vehicle. You need to set the instance variables name and capacity respectively from these
parameters.
? getName(), getCapacity()
These methods should return the respective instance variable; the vehicle’s name and vehicle’s capacity (all set in
the constructor).
2.2.2 Implement the Address class
An Address is represented by a number, street, suburb and postcode. The number is a two or three digit positive
number. The street and suburb are strings and you can assume valid values will be used. The postcode contains only
4 numbers, with the first 2 digits between 1-4 and the last 2 digits between 0-9. The postcode will be represented
as a string.
? Address(int number, string street, string suburb, string postcode)
The constructor method sets the initial values of the number, street, suburb and postcode parameters.
? getNumber(), getStreet(), getSuburb() and getPostcode()
These methods return respective instance variables; the number, street, suburb and postcode.
? int number
This number must be a two or three digit positive number. If the number passed in to the constructor doesn’t fit
this criteria, then a default number of 10 should be assigned.
? string postcode
This postcode must be a 4 digit number. The first two digits of the postcode must be between 1-4 inclusive. The
last two digits must be between 0-9 inclusive. If the postcode passed in to the constructor doesn’t meet these
criteria, it should be given the default value of “1111”.
? void changeAddressTo(int number, string street, string suburb, string postcode)
This function sets the new number, street, suburb and postcode values for the respective Address. Similar to the
constructor, any values that don’t fit the previously mentioned criteria should result in the field being replaced with
the default values mentioned above.
2.2.3 Testing Task 1
Testing code in this assignment works in a similar way to Assignment 1. When you are ready to test your code, you
can compile and run the tests by executing the command make test from the command line console. Alternatively
you can use Eclipse or another IDE.
Making sure that your program passes all of the tests you have been given will not guarantee that you will get
100% of the marks for this assignment, but it will mean that you get at least some marks for the parts that work
according to those tests. Writing your own tests or extending the ones you have been given is strongly recommended,
as there are many requirements in this assignment that the existing tests do not cover. Look at the assignment
specifications, and think carefully about which specifications were explicitly mentioned but there aren’t test cases
provided to you (for example, valid ranges of number or postcode).
2.3 Implement the Humans [Task 2]
You will complete the Human, Civilian, Staff, Suspect, Victim, PoliceOfficer, Paramedic and FireFighter
classes defined in the respective header files within the Emergency Services folder (e.g. Emergency Services/Human.hpp).
The implementation files for most of these classes have also already been created for you with blank implementations
for the methods, but some you will need to add yourself before the code compiles. The aim of this task is to create
objects to represent people that will be involved with emergencies. A human instance is identified by their personal
2
name. If the person is staff, they will have a name and we also want to save their unique staff ID. Moreover, the
staff can also perform a task that’s required at the emergency. Police officers, paramedics and firefighters are three
types of staff that our system wants to save info about. If the staff member is a police officer, their task is to catch
the suspect. If the staff member is a paramedic their task is to treat the victim. The firefighter doesn’t have a
specific task that differs from a general staff member. We should be able to check if a staff member has completed
their job. For a civilian, their name must be saved. Victims and suspects are two types of civilians we would like to
differentiate. If the civilian is a victim, we would like to know if they’ve been treated and by how many paramedics.
If they are a suspect, we would like to know if they’ve been caught and by how many police officers. The following
functions are other functions which are related to classes:
? The Civilian class:
The Civilian class will contain information about the debt owed by the civilian.
void increaseDebt(int debt) Add the given debt to the civilian’s total debt.
void decreaseDebt(int debt) Subtract the specified debt from the civilians total debt. Make sure that the debt
is never negative. If this method is called, and the resulting debt is negative, then it should be set to zero.
Don’t overpay your debt!!
? The Staff class:
The Staff class contains information about whether they have completed their job or not, and the Address of the
emergency they have been assigned to. Information about their name is stored in the Human class. Information
about their ID number (an int) is stored in the Staff class. The staff ID number should be unique. This will start
at 0 for the first staff member created, and increase by 1 for every new staff member.
bool isAssigned() Returns true if the Staff member has been assigned to an emergency.
bool isJobComplete() Returns true if the Staff member has completed their job.
int getID() Returns the unique ID of the Staff member.
void performJob() The staff member should perform their job and update their status accordingly. For a PoliceOfficer
this is making sure their assigned suspect is caught. For a Paramedic this is making sure their assigned
victim is treated. If a staff member doesn’t have any assigned targets they should just store that their job
has been completed. As multiple police officers can be assigned to one suspect, they should still update their
job status to complete even if the suspect has already been caught (more on this in the Suspect class). The
same applies to Paramedics/Victims.
? The FireFighter class:
As firefighters will not have an assigned suspect or victim, they should just store that their job has been completed
to perform their job, the same as any general staff member would.
? The PoliceOfficer class:
The PoliceOfficer class should be able to perform their job as described above, and contain information about the
Suspect that they have been assigned.
void assignSuspect(Suspect* suspect) Assigns the Suspect to this police officer.
Suspect* getAssignedSuspect() Returns the Suspect this police officer has been assigned. If they have not been
assigned it should return null (remember we are using 0 in this course).
? The Paramedic class:
The Paramedic class should be able to perform their job as described above, and contain information about the
victim that they have been assigned.
void assignVictim() Assigns the victim to this paramedic
3
Victim* getAssignedVictim() Returns the victim this staff member has been assigned. If they have not been
assigned it should return null (remember we are using 0 in this course).
? The Victim class:
The Victim class should be as described above, and contain information about the whether they have been treated
and by how many paramedics.
bool isTreated() Returns true if the victim has been treated by one or more paramedics.
int getAmountTreatedBy() Returns the number of times this Victim has been treated by different paramedics
(multiple paramedics may be assigned to one victim).
? The Suspect class:
The Suspect class should be as described above, and contain information about the whether they have been caught
and by how many police officers.
bool isCaught() Returns true if the suspect has been caught by one or more police officers
int getCaughtByAmount() Returns the number of police officers that caught this victim (multiple police officers
may be assigned to one suspect).
As you can see some of the features are repeated several times. For example, all of these entities have a name.
PoliceOfficers, Paramedics and FireFighters all have an ID and must all perform a job. Some things are unique,
such as only police officers have assigned suspects, only paramedics have assigned victims. You therefore need to
consider your design and where you place members/methods. This decreases the repetition by using inheritance
where appropriate. If you implement methods in a base class, you might have to delete the code for the declarations
and implementations of those methods in the derived classes so they aren’t overridden when you don’t want them
to be. Remember your design will be marked for this assignment!
? Testing task 2
The tests for these additional Human subclasses can be enabled by uncommenting the following line at the top of
test.cpp:
// # define ENABLE_T2_TESTS
Once the Task 2 tests are enabled, run make test to execute all of the currently enabled tests. Remember that
not all aspects of these classes are tested in the tests you have been given, so don’t assume the task is complete
once all of the tests pass.
2.4 Implementing the Emergency class [Task 3]
In this section you need to implement the Emergency class. The Emergency class includes information about
the address, suspect, victim, assigned staff and status of the Emergency. You will need to complete the relevant
constructor and getter methods. The emergency class will need to be able to have staff members assigned to the
emergency and stored in a vector. Note that they aren’t assigned at construction of the emergency. An emergency
will also have 4 different Status values which should be defined by a Status enum. These are CRITICAL, ASSIGNED,
TRANSPORTED and COMPLETED. Each emergency will begin in the CRITICAL status. When staff members are assigned
to the emergency, it will change to the ASSIGNED status. When the staff members are transported to the emergency,
it will change to the TRANSPORTED status. If the emergency is in the transported state, it can be resolved by
the assigned staff members. This occurs by all assigned staff members performing their job. After all staff have
performed their job, the emergency will change to the COMPLETE status.