1

I have a queue class where I implement the queue structure.

#include "queue.h"

Queue::Queue()
{


}

Queue::Queue(int size){
    front = rear = -1;
    this->size = size;
    Q = new int[size];
}

void Queue::enqueue(int x){
    if (rear == size -1 ){
        cout << " its full" << endl;
    }else{
        rear ++;
        Q[rear] = x;
    }
}

int Queue::dequeue(){
    int x= -1;
    if (rear == front){
        cout << " its empty"<<endl;
    }else{
        front ++;
        x = Q[front];
    }

    return x;
}

void Queue::Display(){
    for(int i= front+1; i<=rear; i++){
        cout << Q[i] << "  ";
    }

    cout << endl;
}

bool Queue::isEmpty(){
    return (size==0);
}
int Queue::peek()
{
    if (isEmpty())
    {
        cout << "UnderFlow\nProgram Terminated\n";
        exit(EXIT_FAILURE);
    }
    return Q[front];
}

In main.cpp, I create multiple queues. I am trying to implement a scheduling algorithm where I need to process each queue in order. The problem starts when I try to go through each queue. I would like to use only one for loop to access the element of each queue rather than for loop for each of them.

Example:

queue[1..N] where N is the number of queues. In for loop, I want to check if queue[i].empty().

srbemr
  • 318
  • 1
  • 2
  • 8

2 Answers2

0

I found a solution to the problem. In the main.cpp, following code solved the issue.

Queue allQueues[4];

allQueues[0] = queue1;
allQueues[1] = queue2;
allQueues[2] = queue3;
allQueues[3] = queue4;

To access:

for(int i=0; i<4; i++){

    if allQueues[i].empty(){
        //do something
    }
}
srbemr
  • 318
  • 1
  • 2
  • 8
0

If you need to generate a specific number of instances of your Queue class that is fixed and known at compile time, your code solution will work. However, if you have a program where new Queue instances need to be created while the program is running, you need to use dynamic memory allocation on the heap.

One approach to this is to create an array or a vector of pointers to your Queue class in main.cpp. The std::vector is more flexible, and it's best to use a smart pointer to create each instance of Queue, although many academic courses won't allow use of the standard template library or of smart pointers, and in that case you need just a normal array of pointers to Queue and use new and delete appropriately.

const int SIZE = 100  //max number of Queue instances
Queue* allQueues[SIZE]; //array of uninitialized pointers to Queue
for (int i = 0; i < SIZE; i++) {  //ensure all pointers are set to null
    allQueues[i] = nullptr;
}

//To make a new Queue instance and insert it into the array:
allQueues[0] = new Queue();
//And when done with that Queue instance, to avoid memory leaks and dangling pointers:
delete allQueues[0];
allQueues[0] = nullptr;

(This is all much better done with std::array, or std::vector, and smart pointers). Note also the memory usage, without this approach you have two full-sized instances of Queue for queue1, instead of the object itself and a pointer to that object. However, one can do the array of pointers thing using only automatic stack allocation as well, but in that case, you don't want to be creating new objects at runtime. For that, it's simple:

Queue* allQueues[4];
allQueues[0] = &queue1;
//etc.

P.S. One problem with your solution is that when you do this assignment:

allQueues[0] = queue1;

You need a copy constructor in your class, or an overloaded '=' operator, to ensure that all of queue1's internals are correctly copied over into the the array of Queue objects, and avoid all the 'shallow copy' issues.

Queue::Queue(const Queue& copySource) {
    this->size = copysource.size;
    this->Q = new int[copysource.size];
    for (int i = 0; i < size; i++) {
        this->Q[i] = copysource.Q[i];
    }

See: Why can I access private variables in the copy constructor?

neutrino_logic
  • 1,289
  • 1
  • 6
  • 11