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


In this model, if class Customer had the following function


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:

if (checkers[i] == NULL)

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:

// print the done shopping message
void Cust::Print_done_shopping()
{
       cout << m_time << ": " << m_name << ....
}

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(ostream &os)
{
       os << m_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).