PREVIOUS PROBLEM FIXED AND UPDATED ARRAYQUEUE.CPP WITH CURRENT VERSION
***CURRENT PROBLEM***
I have gotten my items that I am enqueueing to correctly pop up in the my program but for some reason my queue is outputting the rear only.
Output:
Item #0: 1
Item #1: 2
Here is the queue: 2
The resize function is used to double the size of the ArrayQueue if the capacity is exceeded and the capacity is halve the size of the array when an item is dequeued if it causes the number of items to be half the capacity or less
ArrayQueue.h:
#ifndef ARRAY_QUEUE_H
#define ARRAY_QUEUE_H
#include "QueueInterface.h"
#include "PrecondViolatedExcep.h"
template<class ItemType>
class ArrayQueue : public QueueInterface<ItemType>
{
public:
ArrayQueue();
ArrayQueue(const ArrayQueue& right);
ArrayQueue operator =(const ArrayQueue& right);
~ArrayQueue();
bool isEmpty() const;
void enqueue(const ItemType& newEntry);
void dequeue();
ItemType peekFront() const;
void print() const;
int getSize();
private:
static const int DEFAULT_CAPACITY = 1;
ItemType* items;
int front;
int back;
int numItems;
int capacity;
void resize(int);
};
#include "ArrayQueue.cpp"
#endif
ArrayQueue.cpp:
#include <iostream>
using namespace std;
template<class ItemType>
ArrayQueue<ItemType>::ArrayQueue() {
front = 0;
back = DEFAULT_CAPACITY - 1;
numItems = 0;
capacity = DEFAULT_CAPACITY;
items = new ItemType[capacity];
}
template<class ItemType>
ArrayQueue<ItemType>::ArrayQueue(const ArrayQueue<ItemType>& right)
{
numItems = right.numItems;
items = new ItemType[strlen(right.items) + 1];
strcpy(items, right.items);
}
template<class ItemType>
ArrayQueue<ItemType> ArrayQueue<ItemType>::operator =(const ArrayQueue& right)
{
if (this != right)
{
numItems = right.numItems;
delete[] items;
items = new ItemType[right.capacity];
strcpy(items, right.items);
}
return *this;
}
template<class ItemType>
ArrayQueue<ItemType>::~ArrayQueue()
{
delete[] items;
}
template<class ItemType>
bool ArrayQueue<ItemType>::isEmpty() const {
return numItems == 0;
}
template<class ItemType>
void ArrayQueue<ItemType>::enqueue(const ItemType& newEntry)
{
//ItemType* temp = new ItemType;
if (isEmpty()) {
//front = back = 0;
back = (back + 1) % capacity;
items[back] = newEntry; //Problem *SOLVED FOR NOW*
//items = temp;
numItems++;
}
else
{
if (numItems == capacity)
{
resize(2 * capacity);
}
back = (back + 1) % capacity;
//back = (back + 1) % capacity;
if (back == capacity - 1)
back = 0;
items[back] = newEntry;
//items = temp;
numItems++;
}
std::cout << std::endl;
std::cout << "Item #" << numItems - 1 << ": " << items[(numItems - 1) % capacity] << std::endl;
std::cout << endl;
}
template<class ItemType>
int ArrayQueue<ItemType>::getSize()
{
return capacity;
}
template<class ItemType>
void ArrayQueue<ItemType>::dequeue()
{
std::cout << std::endl;
std::cout << "Item Being removed: " << items[front] << std::endl;
if (isEmpty())
{
throw PrecondViolatedExcep();
}
else
{
if (numItems == capacity / 2)
{
resize(capacity / 2);
}
if (back == front)
back = front = 0;
else
{
front = (front + 1) % capacity;
numItems--;
}
std::cout << std::endl;
}
std::cout << "New item at front: " << items[front] << std::endl;
std::cout << std::endl;
}
template<class ItemType>
ItemType ArrayQueue<ItemType>::peekFront() const
{
if (isEmpty()) {
throw PrecondViolatedExcep("peekFront() called with empty queue");
}
return items[front];
}
template<class ItemType>
void ArrayQueue<ItemType>::print() const {
std::cout << "Here is the queue: ";
if (isEmpty()) {
std::cout << "empty";
}
else {
for (int i = front; i != back; i = (i + 1) % capacity) {
std::cout << items[i] << " ";
}
std::cout << items[back];
}
}
template<class ItemType>
void ArrayQueue<ItemType>::resize(int newCapacity)
{
ItemType* temp = new ItemType[newCapacity];
for (int i = 0; i < capacity; i++)
{
int index = (front + i) % capacity;
temp[i] = items[index];
}
front = 0;
back = numItems - 1;
delete[] items;
items = temp;
capacity = newCapacity;
}
QueueInterface.h:
#ifndef QUEUE_INTERFACE_
#define QUEUE_INTERFACE_
template<class ItemType>
class QueueInterface
{
public:
/** Sees whether this queue is empty.
@return True if the queue is empty, or false if not. */
virtual bool isEmpty() const = 0;
/** Adds a new entry to the back of this queue.
@post If the operation was successful, newEntry is at the
back of the queue.
@param newEntry The object to be added as a new entry.
@return True if the addition is successful or false if not. */
virtual void enqueue(const ItemType& newEntry) = 0;
/** Removes the front of this queue.
@post If the operation was successful, the front of the queue
has been removed.
@return True if the removal is successful or false if not. */
virtual void dequeue() = 0;
/** Returns the front of this queue.
@pre The queue is not empty.
@post The front of the queue has been returned, and the
queue is unchanged.
@return The front of the queue. */
virtual ItemType peekFront() const = 0;
/** Destroys object and frees memory allocated by object. */
virtual ~QueueInterface() { }
}; // end QueueInterface
#endif
PrecondViolatedExcep.cpp:
#include "PrecondViolatedExcep.h"
PrecondViolatedExcep::PrecondViolatedExcep(const std::string& message)
: std::logic_error("Precondition Violated Exception: " + message)
{
}
PrecondViolatedExcep.h:
#ifndef PRECOND_VIOLATED_EXCEP_H
#define PRECOND_VIOLATED_EXCEP_H
#include <stdexcept>
#include <string>
class PrecondViolatedExcep : public std::logic_error
{
public:
PrecondViolatedExcep(const std::string& message = "");
};
#endif
Client file used for testing Functions:
#include <iostream>
#include "ArrayQueue.h"
#include "PrecondViolatedExcep.h"
#include "QueueInterface.h"
using namespace std;
int main()
{
ArrayQueue<int> attempt;
/*attempt.enqueue(6);
attempt.enqueue(5);
attempt.enqueue(4);
attempt.enqueue(3);
attempt.enqueue(2); */
attempt.enqueue(1);
attempt.enqueue(2);
attempt.enqueue(3);
attempt.print();
cout << "The capacity is " << attempt.getSize();
}
strcpy. You'll find it's really only useful for copying null-terminated strings. Using it on anything else is fatal. The program right not crash right away, but it's only a matter of time.#include "ArrayQueue.cpp"can also be a bad idea. Many build tools will see that cpp file and assume it needs to be compiled and linked. When it does, you'll get multiple definition linker errors. It also confuses people reading the code. Rename ArrayQueue.cpp to something harmless and associated with headers like ArrayQueue.hppArrayQueueconstructor doesn't initializeitems. Leaves the object in a risky condition. When you enqueue into an empty list, it's beyond empty. It doesn't exist. Kaboom.