To implement a queue using plain arrays, just treat it circularly - so as soon as you run out of space in the array, wrap back around to 0. You'll need to keep a record of front and rear, as you note. As an example (where X represents an item in the queue):
// Rear is where to enqueue into, Front is where to dequeue from
Empty Array:
| - - - |
Front = -1, Rear = 0
Enqueue()
| X - - |
Front = 0, Rear = 1
Enqueue()
| X X - |
Front = 0, Rear = 2
Dequeue()
| - X - |
Front = 1, Rear = 2
Enqueue()
| - X X |
Front = 1, Rear = 0 // Looped around
Dequeue()
| - - X |
Front = 2, Rear = 0
Enqueue()
| X - X |
Front = 2, Rear = 1
You just have to use modular arithmetic to wrap around. Of course, this is limited in size (once you run out of elements, you'd have to allocate more memory), but that's just what you get when dealing with arrays.
Here's some code as a start (I haven't checked it at all):
// Private class variables:
// These should be set in the constructor of your queue class
unsigned int rear = 0; // back of the queue
unsigned int front = -1; // front of the queue
unsigned int numStored = 0;
unsigned int length;
Object* array = new Object[length];
QueueAr::Enqueue(Object& obj)
{
if (front == rear)
{
// Throw an exception: queue is full!
}
else
{
array[rear] = obj; // Insert the object at the back
rear++;
rear = rear % length;
numStored++;
}
}
// For kicks, here's the queue code
QueueAr::Dequeue(Object& obj)
{
if (numStored == 0)
{
// Throw an exception: queue is empty!
}
front++;
front = front % length;
numStored--;
}