1

I am trying to make a queue implementing a linked list but am running into a compiler error. The error is coming from the overloaded assignment operator function on the line where I call the destructor (marked with an all-caps comment). I have a hunch it is a simple fix that has something to do with the syntax of my constructor/destructor declarations.

The error I am getting states the following code: error C2512: 'Queue<char>::Queue' : no appropriate default constructor available

It mentions no constructor, but the line it refers to is the one below where I am trying to call the destructor.

Thanks in advance for your help.

#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
using namespace std;

template <class Type>
class Queue     // Create a Queue data structure implementing a linked list
{
    private:        // The private members
        struct Cell     // The Cell class will be the blueprints for each link in the list
        {
            Type data;      // The information held by the cell
            Cell* next;     // The link to the next cell
        };

        Cell* first = NULL;
        Cell* last = NULL;


    public:     // The public members
        Queue(Type);
        bool isEmpty();
        void push(Type);
        Type pop();
        Queue<Type>& operator=(Queue<Type>&);
        friend ostream& operator<<(ostream&, const Queue<Type>&);
        ~Queue();
};


template<class Type>
Queue<Type>::Queue(Type inputData)      // Constructor that initializes the queue with a new cell that last and first point to
{
    first = new Cell;

    first->data = inputData;
    first->next = NULL;

    last = first;
}




template<class Type>
Queue<Type>& Queue<Type>::operator=(Queue<Type>& queue)     // Overload "=" so that it performs a deep copy of a Queue object
{
    if (!queue.isEmpty())
    {
        ~Queue();      // HERE IS THE ERROR LINE

        Cell* rhs = queue.first;

        while (rhs != NULL)
        {
            push(rhs->data);
            rhs = rhs->next;
        }
    }

    return *this;
}




template<class Type>
Queue<Type>::~Queue()       // Destructor that deallocates all of the memory used by the queue.
{
    if (!isEmpty())     // We only need to deallocate the queue if it is non-empty
    {
        Cell *link = last;

        while (link != NULL)        // Until we reach the end of the queue, keep deleting each link
        {
            pop();
        }

        first = NULL;
        last = NULL;
    }
    else        // If the queue is already empty, let the user know
    {
        cout << "Cannot call destructor. The list is already empty.\n";
    }
}
#endif
D Drmmr
  • 1,223
  • 8
  • 15
Peter
  • 498
  • 3
  • 15

3 Answers3

1

Check out this thread: Can i call destructor from its class method?. An easy way around this is to make a function to empty the queue, then call it from the destructor and assignment operator.

template<class Type>
void Queue<Type> empty(){
    if (!isEmpty())     // We only need to deallocate the queue if it is non-empty
    {
         Cell *link = last;

        while (link != NULL)        // Until we reach the end of the queue, keep deleting each link
        {
            pop();
        }

        first = NULL;
        last = NULL;
    }
    else        // If the queue is already empty, let the user know
    {
        cout << "Cannot call empty. The list is already empty.\n";
    }
}

template<class Type>
Queue<Type>& Queue<Type>::operator=(Queue<Type>& queue)     // Overload "=" so that it performs a deep copy of a Queue object
{
    if (!queue.isEmpty())
    {
        empty();      // Tada, no more error

        Cell* rhs = queue.first;

        while (rhs != NULL)
        {
            push(rhs->data);
            rhs = rhs->next;
        }
    }

    return *this;
}




template<class Type>
Queue<Type>::~Queue()       // Deconstructor that deallocates all of the memory used by the queue.
{
    empty();
}
Community
  • 1
  • 1
kwierman
  • 441
  • 4
  • 11
  • This was helpful, thank you. I am now getting an error with some sort of "unresolved external symbol." Bleh – Peter Oct 16 '14 at 06:54
0

This has nothing to do with template.

If you declare any constructor for your class, the compiler synthesized default constructor(i.e. the one that takes no arg) is deleted.

You have to define Queue() yourself.

BTW, a using directive in the global scope is not a good idea.

Jamboree
  • 5,139
  • 2
  • 16
  • 36
0

I guess you define a queue without parameter, like

Queue<char> quCh;

If you want to do this, you must define a constructor without parameter.

Queue();

or you must define your queue like this:

Queue<char> quCh('a');
Zhuang Ma
  • 614
  • 7
  • 12