First I'll explain what I'm trying to do. I am programming an airline check-in line. I am using a queue ADT to represent a the line. The data type of the a queue is a pointer to my Customer class. In my Customer class, whenever a customer leaves the line, a method in the Customer class named talk will print out a canned response. Here is what it looks like:

string Customer::talk()
{
      cout << firstName << ' ' << lastName 
           << " says, \"This is the worst airline!\"." << endl;
}

All the data is read in from an input file. It includes a command 'add' to add the customer to the queue. When I try to remove customers from the queue, talk only prints out the last customer read in however many times a customer was added. So I get something like this:

John Malkovich says, "This is the worst airline!".
John Malkovich says, "This is the worst airline!".
John Malkovich says, "This is the worst airline!".
John Malkovich says, "This is the worst airline!".
John Malkovich says, "This is the worst airline!".
John Malkovich says, "This is the worst airline!".

I believe my problem is in main:

Queue q;
	Customer c;
	Customer *cp = &c;
	string command, fname, lname, stat;
	
	while(infile >> command)
	{
		//After reading in the command, calling the approprate function
		if(command == "add")
		{
			infile >> fname;
			c.setFirstName(fname);
			cout << fname << ' ';
			infile >> lname;
			c.setLastName(lname);
			cout << lname << ' ';
			infile >> stat;
			c.setStatus(stat);
			cout << stat << endl;
			q.enqueue(cp);
		}
	}
	
	while(!q.isEmpty())
	{
		q.getFront(cp);
		cp->talk();
		q.dequeue();
	}

is with my pointers and the way I'm storing my data. Could someone please help?

Recommended Answers

All 4 Replies

You need to post the Queue class, especiall the enqueue() method. My hunch is that it does not make its own copy of the Customer class, but just uses the same pointer that is passed to it in the parameter. That's why it would wind up with all queue nodes pointing to the same Customer object.

queue.h:

#ifndef QUEUE_H
#define QUEUE_H
/** @file QueueP.h */

#include "Customer.h"
#include "QueueException.h"
typedef Customer* QueueItemType;

/** @class Queue
 * ADT queue - Pointer-based implementation. */
class Queue
{
public:
// Constructors and destructor:

   /** Default constructor. */
   Queue();

 /** Copy constructor.
  * @param Q The Queue to copy. */
   Queue(const Queue& Q);

   /** Destructor.          */
   ~Queue();

// Queue operations:

   /** Determines whether this queue is empty.
    * @pre None.
    * @post None.
    * @return True if this queue is empty; otherwise returns
    *         false. */
   bool isEmpty() const;

   /** Inserts an item at the back of this queue.
    * @pre newItem is the item to be inserted.
    * @post If the insertion is successful, newItem is at the back
    *       of this queue.
    * @throw QueueException  If memory allocation fails. */
   void enqueue(const QueueItemType& newItem)
        throw(QueueException);

   /** Dequeues the front of this queue.
    * @pre None.
    * @post If this queue is not empty, the item that was added to
    *       this queue earliest is deleted.
    * @throw QueueException  If this queue is empty. */
   void dequeue() throw(QueueException);

   /** Retrieves and deletes the front of this queue.
    * @pre None.
    * @post If this queue is not empty, queueFront contains the item
    *       that was added to this queue earliest, and the item is
    *       deleted.
    * @throw QueueException  If this queue is empty. */
   void dequeue(QueueItemType& queueFront) throw(QueueException);

   /** Retrieves the item at the front of this queue.
    * @pre None.
    * @post If this queue is not empty, queueFront contains the item
    *       that was added to this queue earliest.
    * @throw QueueException  If this queue is empty. */
   void getFront(QueueItemType& queueFront) const
      throw(QueueException);

private:
   /** The queue is implemented as a linked list with one external
    *  pointer to the front of the queue and a second external
    *  pointer to the back of the queue. */
   struct QueueNode
   {  QueueItemType  item;
      QueueNode     *next;
   }; // end QueueNode
   QueueNode *backPtr;
   QueueNode *frontPtr;
}; // end Queue
// End of header file.

#endif

queue.cpp:

/** @file QueueP.cpp */

#include <cstddef>   // for NULL
#include <cassert>   // for assert
#include <new>       // for bad_alloc
#include "queue.h"  // header file

using namespace std;

Queue::Queue() : backPtr(NULL), frontPtr(NULL)
{
}  // end default constructor

Queue::Queue(const Queue& Q)
{  
}  // end copy constructor

Queue::~Queue()
{
   while (!isEmpty())
      dequeue();
   assert ( (backPtr == NULL) && (frontPtr == NULL) );
}  // end destructor

bool Queue::isEmpty() const
{
   return backPtr == NULL;
}  // end isEmpty

void Queue::enqueue(const QueueItemType& newItem)
   throw(QueueException)
{
   try
   {  // create a new node
      QueueNode *newPtr = new QueueNode;

      // set data portion of new node
      newPtr->item = newItem;

      newPtr->next = NULL;

      // insert the new node
      if (isEmpty())
	 // insertion into empty queue
	 frontPtr = newPtr;
      else
	 // insertion into nonempty queue
	 backPtr->next = newPtr;

      backPtr = newPtr;  // new node is at back
   }
   catch (bad_alloc e)
   {
      throw QueueException(
	 "QueueException: enqueue cannot allocate memory.");
   }  // end try
}  // end enqueue

void Queue::dequeue() throw(QueueException)
{
   if (isEmpty())
      throw QueueException(
	 "QueueException: empty queue, cannot dequeue");
   else
   {  // queue is not empty; remove front
      QueueNode *tempPtr = frontPtr;
      if (frontPtr == backPtr)   // special case?
      {  // yes, one node in queue
         frontPtr = NULL;
         backPtr = NULL;
      }
      else
         frontPtr = frontPtr->next;

      tempPtr->next = NULL;  // defensive strategy
      delete tempPtr;
   }  // end if
}  // end dequeue

void Queue::dequeue(QueueItemType& queueFront)
   throw(QueueException)
{
   if (isEmpty())
      throw QueueException(
	 "QueueException: empty queue, cannot dequeue");
   else
   {  // queue is not empty; retrieve front
      queueFront = frontPtr->item;
      dequeue();  // delete front
   }  // end if
}  // end dequeue

void Queue::getFront(QueueItemType& queueFront) const
   throw(QueueException)
{
   if (isEmpty())
      throw QueueException(
	 "QueueException: empty queue, cannot getFront");
   else
      // queue is not empty; retrieve front
      queueFront = frontPtr->item;
}  // end getFront
// End of implementation file.

I forgot that I didnt add the copy constructor!

Queue::Queue(const Queue& Q)
{  
	if (Q.frontPtr == NULL)
		frontPtr = NULL;  // original list is empty

	else
	{  // copy first node
		frontPtr = new QueueNode;
		frontPtr->item = Q.frontPtr->item;

		// copy rest of list
		QueueNode *newPtr = frontPtr;    // new list pointer
		for (QueueNode *origPtr = Q.frontPtr->next; origPtr != NULL; origPtr = origPtr->next)
		{  
			newPtr->next = new QueueNode;
			newPtr = newPtr->next;
			newPtr->item = origPtr->item;
		}  // end for

		newPtr->next = NULL;
   }  // end if
}

I'm working on the same assignment and that is the exact problem I'm having. Did you figure it out?

BTW, what university do you go to?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.