Arrays of Pointers -- Some hints for Kwik-E-Mart
Simulation (Program 5)
Questions on Program 5
Work on program
5
Lab 10
CSCI 112
Goals:
Present some hints for
the Kwik-E-Mart simulation program (Program 5)
Answer questions
about program 5
Allow students time to work on program 5
Checkers: An Array of Pointers
A Kwik-E-Mart checker is
either helping a customer or sitting idle. Since customers are
represented by a class (Cust) we can model a checker as a
pointer.
Consider the case of a store that always had one
checker:
Cust *checker = NULL;
// when the
checker is given a customer to serve
checker = customer;
//
when the checker is done serving a customer
checker = NULL;
//
we can tell if the checker is serving anyone like this:
if
(checker != NULL)
checker is serving a
customer
else
checker is not serving a
customer
bool
Cust::done_checkout(int time)
{
if (time >=
m_done_time)
return true;
else return false;
}
We could call it like this:
if
(checker->done_checkout(current_time))
{
checker->print_done_checking_out(os);
delete checker;
checker = NULL;
}
The
Kwik-E-Mart simulation allows the user to specify the number of
checkers at run time. Since we don't know the number of checkers
at compile time, we have to create the array of checkers at run time.
If we pass the number of checkers to the run_simulation() function, we can use it to create a local array of checkers:
run_simulation(int
num_checkers, ...)
{
Cust *checkers[num_checkers];
// now initialize all the checkers to NULL.
}
Since we only need the array of checkers in
run_simulation() this is the easiest way to create it.
In the first example above, we used our checker to call a member
function of class
Cust:
if
(checker->done_checkout(current_time))
When you have an
array of pointers to objects, you can use it as follows:
if (checkers[i]->done_checkout(current_time))
And when the checker become idle we can do the
following:
checkers[i] = NULL;
And we can ask if a checker is idle like this:
Priority Queue
Consider a queue of integers. The dequeue function needs to return two pieces of information: did the dequeue succeed and what value was removed. Typically this is done by using a bool return and a reference parameter:
bool Iqueue::dequeue(int & value_removed)
The reason we need both is because there is no integer value that we can return to indicate the queue was empty. For example, if we decide that returning 0 means the queue was empty, what would happing if there was a 0 in the queue? There is not integer that we can use because it is valid for any integer to be inserted into the queue.
Now consider a queue of pointers to Cust. Since NULL is not a "valid" pointer we can use it to indicate the queue was empty:
Cust *Pqueue::dequeue()
This function return a non-null pointer if the queue was not empty and the dequeue succeeded, and it returns NULL if the queue was empty.
Program Output
In an object-oriented program, the
goal is to put the functionality in the same object that holds the data.
Printing a class Cust is inherently
part of a Cust. The printed version of a Cust is part of the
object.
Thus when you print a Cust, it
should be done by member functions of class Cust. For example:
The problem with this function is
that it always prints to cout, and your program is suppose to print to
a file.
The solution is to pass an ostream
object to Print() so it can print directly to the file:
// print the done shopping message to the
given ostream
void Cust::Print_done_shopping(int time, ostream &os)
{
os << time << ": " <<
m_name << ....
}
The above prints to the given
ostream.
The os is the file stream you open
in main(). Since customers are printed
in run_simulation(...), you will need to pass the os to
run_simulation() along with the other argument(s).