1

I am facing a very specific problem when trying to implement a generic queue in C++. Here is the code:

template <class T> class Queue  {

    private:
        T * queue;
        int front;
        int back;
        int MAX_SIZE;

    public:
        Queue(){
            Queue(SOME_PREDEFINED_CONSTANT);
        }

        Queue(int size){
            queue = new T[size];
            MAX_SIZE = size;
            front = 0;
            back = 0;
            cout << "inside constructor:" << " back= " << back <<  " front=" << front << endl;

        }

        void push(const T entry){

            if(back < MAX_SIZE){
                queue[back] = entry;
                back++;
            }
        }

        T peek(){

            return queue[front]; 
        }

        void pop(){

            if(size() > 0){
                front++;
            }
            if(front==back){
                front = 0;
                back = 0;
            }
        }

        int size(){
            cout << "size:" << " back=" << back <<  " front=" << front << endl;
            return (back-front);
        }
};

When I am initializing the queue, like this: Queue <int> q;, I get the correct values of back and front inside the constructor; The output:

inside constructor: back=0 front=0

But when I am asking for the size of the queue, like this: q.size() (without any push/pop operation), I get very weird values of back and front. One sample output:

size: back=32766 front=-746749592

Can anyone please point out what I am doing wrong here?

Ahsan Tarique
  • 581
  • 1
  • 11
  • 22
  • 3
    This: `Queue(){ Queue(SOME_PREDEFINED_CONSTANT);` is not doing what you think it is doing. – Fantastic Mr Fox Mar 21 '18 at 13:07
  • 3
    `Queue() : Queue(SOME_PREDEFINED_CONSTANT) {}` As written, your default constructor does not initialize any members. In its body, it creates and immediately discards a temporary `Queue`, which has zero effect. – Igor Tandetnik Mar 21 '18 at 13:07
  • Read about the [rule of 0/3/5](http://en.cppreference.com/w/cpp/language/rule_of_three). – YSC Mar 21 '18 at 13:07
  • In addition to @Igor: `Queue(int size = SOME_PREDEFINED_CONSTANT)` achieves the same as "two in one". If `Queue` is constructed without argument, `SOME_PREDEFINED_CONSTANT` is used as default. – Scheff's Cat Mar 21 '18 at 13:10

1 Answers1

4

When you do

Queue(){
    Queue(SOME_PREDEFINED_CONSTANT);
}

What happens is that you inside the default constructor create a temporary object which immediately go out of scope and is destructed.

There are two ways of solving this:

  1. The "new" way using a constructor initializer list and delegating constructors:

    Queue() : Queue(SOME_PREDEFINED_CONSTANT)
    { /* empty */ }
    
  2. The "old" way using default arguments:

    template <class T> class Queue  {
        ...
    
    public:
        Queue(int size = SOME_PREDEFINED_CONSTANT){
            ...
        }
        ...
    };
    
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621