Search code examples
c++templatespointersdynamic-memory-allocationclass-template

How to define a template for pointers and dynamic memory allocation?


I've made a class template called Queue but I'm having problems trying to instanciate it with a pointer to another class called Worker as the type. Queue<Worker*>

The problem I think comes with this concrete Queue method:

// Add item to queue
template <typename Type>
bool Queue<Type>::enqueue(const Type& item)
{
    if (isfull())
        return false;
    Node* add = new Node; // create node
    // on failure, new throws std::bad_alloc exception
    add->item = item; // set node pointers (shallow copying!!!!!)
    add->next = nullptr;
    items++;
    if (front == nullptr) // if queue is empty,
        front = add; // place item at front
    else
        rear->next = add; // else place at rear
    rear = add; // have rear point to new node
    return true;
}

In the case of the type parameter being a pointer I need to copy the pointed-to value, not the address (I'm using dynamic memory management) to avoid the program crashing.

I don't know how to solve this with a template.

Any help?


Solution

  • Although it will cause a bit of code duplication, you can create a specialization of your Queue class for instantiations with pointer-types. My recommendation in order to reduce the amount of code duplication would be to create a base-class that each specialized class will inherit from, where the base-class contains all the methods and members that will not change depending on the type that the class is instantiated with.

    So for instance:

    template<typename T>
    base_queue; //keep everything "common" in this class
    
    template<typename T>
    queue : public base_queue<T> { ... }; //unspecialized queue class
    
    template<typename T>
    queue<T*> : public base_queue<T> { ... }; //pointer specialized version
    

    Now in the specialized version of your Queue<T*> class, your enqueue method can look like the following:

    template <typename T>
    bool Queue<T*>::enqueue(const T* item)
    {
        //... code
    
        add->item = *item; // copy the value being pointed to, not the pointer itself
    
        //... more code
    
        return true;
    }