Search code examples
c++templateslinked-liststack

How to use template for implementing STACK using LINKEDLIST in cpp


So i am trying to create a c++ file which implements stack and all its functions(push,pop,getTop,etc). I want to use Template so that i can make this Stack class for multiple datatypes. I am using linked list to store the data. Here is some example of stack i have implemented using linked list.

#include<iostream>
using namespace std;

template <class T>

class Node{
public:
      T data;
      Node *next;
      Node()
      {
            next = NULL;
      }
};

class Stack
{
      Node *top;
public:
      Stack();
      int isEmpty();
      int isFull();
      void push(T data);
      T pop();
      void display();
};

Stack :: Stack()
{
      top = NULL;
}

int Stack :: isEmpty()
{
      if(top == NULL)
      {
            return 1;
      }
      else
      {
            return 0;
      }
}

int Stack :: isFull()
{
      int temp;
      Node *t = new Node;

      if(t==NULL)
      {
            temp = 1;
      }
      else
      {
            temp = 0;
      }

      delete t;
      return temp;
}

void Stack :: push(T data)
{
      Node *n;

      if(isFull())
      {
            cout<<"\nStack overflow";
      }
      else
      {
            n = new Node;
            n->data = data;
            n->next = top;
            top = n;
      }

}

int Stack :: pop()
{
      Node *t;
      T temp;

      if(isEmpty())
      {
            return temp;
      }
      else
      {
            t = top;
            top = top->next;
            temp = t->data;
            delete t;
            return temp;
      }
}

void Stack :: display()
{
      Node *p = top;
      while(p != NULL)
      {
            cout<<"\n"<<p->data;
            p = p->next;
      }
}

So this is a preview of what i am trying to do, but i don't want to create different node and stack class for different data types. How can i achieve that using Templates. I tried it myself but i am getting lots of error and cant seem to understand why. Thanks.


Solution

  • I suggest making the Node into an inner class of Stack. There's no need for users to be able to see it.

    #include<iostream>
    #include<utility>
    
    template<class T>
    class Stack {
        struct Node {  // inner class
            T data;
            Node *next;
        };
    
        Node* top = nullptr;
        size_t m_size = 0;
    
    public:
        Stack() = default;
    
        // rule of five - no copying, only moving allowed
        Stack(const Stack&) = delete;
        Stack(Stack&& rhs) noexcept :
            top(std::exchange(rhs.top, nullptr)), m_size(rhs.m_size) 
        {}
        Stack& operator=(const Stack&) = delete;
        Stack& operator=(Stack&& rhs) noexcept {
            std::swap(top, rhs.top);
            m_size = rhs.m_size;
            return *this;
        }
        ~Stack() {
            while(top) {
                delete std::exchange(top, top->next);
            }
        }
    
        bool empty() const { return m_size == 0; }
        size_t size() const { return m_size; }
    
        void push(const T& data) {
            top = new Node{data, top};
            ++m_size;
        }
    
        T pop() {
            T rv = std::move(top->data);
            delete std::exchange(top, top->next);
            --m_size;
            return rv;
        }
    };
    

    Demo