Using a stack defined by nested class templates - C++ template

C++ examples for template:template class

Description

Using a stack defined by nested class templates

Demo Code

#include <iostream>
#include <string>
using std::string;
#include <stdexcept>

template <typename T>
class Stack/*from w  w w. j a va 2s  . c o m*/
{
  private:
    // Nested class
    class Node
    {
      public:
        T* pItem {};                           // Pointer to object stored
        Node* pNext {};                        // Pointer to next node

        Node(T& item) : pItem {&item} {}       // Create a node from an object
    };

    Node* pHead {};                            // Points to the top of the stack
    void copy(const Stack& stack);             // Helper to copy a stack
    void freeMemory();                         // Helper to release free store memory

  public:
    Stack() = default;                         // Default constructor
    Stack(const Stack& stack);                 // Copy constructor
    ~Stack();                                  // Destructor
    Stack& operator=(const Stack& stack);      // Assignment operator

    void push(T& item);                        // Push an object onto the stack
    T& pop();                                  // Pop an object off the stack
    bool isEmpty() {return !pHead;}            // Empty test
};

// Copy constructor
template <typename T>
Stack<T>::Stack(const Stack& stack)
{
  copy(stack);
}

// Helper to copy a stack
template <typename T>
void Stack<T>::copy(const Stack& stack)
{
  if(stack.pHead)
  {
    pHead = new Node {*stack.pHead};           // Copy the top node of the original
    Node* pOldNode {stack.pHead};              // Points to the top node of the original
    Node* pNewNode {pHead};                    // Points to the node in the new stack

    while(pOldNode = pOldNode->pNext)          // If it's nullptr, it's the last node
    {
      pNewNode->pNext = new Node {*pOldNode};  // Duplicate it
      pNewNode = pNewNode->pNext;              // Move to the node just created
    }
  }
}

// Assignment operator
template <typename T>
Stack<T>& Stack<T>::operator=(const Stack& stack)
{
  if (this != &stack)                          // If objects are not identical
  {
    freeMemory();                              // Release memory for nodes in lhs
    copy(stack);                               // Copy rhs to lhs
  }
  return *this                                 // Return the left object
}

// Helper to release memory for a stack
template <typename T>
void Stack<T>::freeMemory()
{
  Node* pTemp {};
  while(pHead)
  {                                            // While current pointer is not null
    pTemp = pHead->pNext;                      // Get the pointer to the next
    delete pHead;                              // Delete the current
    pHead = pTemp;                             // Make the next current
  }
}

// Destructor
template <typename T>
Stack<T>::~Stack()
{
  freeMemory();
}

// Push an object onto the stack
template <typename T>
void Stack<T>::push(T& item)
{
  Node* pNode {new Node(item)};                // Create the new node
  pNode->pNext = pHead;                        // Point to the old top node
  pHead = pNode;                               // Make the new node the top
}

// Pop an object off the stack
template <typename T>
T& Stack<T>::pop()
{
  T* pItem {pHead->pItem};                     // Get pointer to the top node object
  if(!pItem)                                   // If it's empty
    throw std::logic_error {"Stack empty"};    // Pop is not valid so throw exception

  Node* pTemp {pHead};                         // Save address of top node
  pHead = pHead->pNext;                        // Make next node the top
  delete pTemp;                                // Delete the previous top node
  return *pItem;                               // Return the top object
}
int main()
{
  const char* words[] {"The", "quick", "brown", "fox", "jumps"};
  Stack<const char*> wordStack;             // A stack of C-style strings

  for (int i {}; i < sizeof(words)/sizeof(words[0]) ; ++i)
    wordStack.push(words[i]);

  Stack<const char*> newStack {wordStack};   // Create a copy of the stack

  // Display the words in reverse order
  while(!newStack.isEmpty())
    std::cout << newStack.pop() << " ";
  std::cout << std::endl;

  // Reverse wordStack onto newStack
  while(!wordStack.isEmpty())
    newStack.push(wordStack.pop());

  // Display the words in original order
  while(!newStack.isEmpty())
    std::cout << newStack.pop() << " ";
  std::cout << std::endl;

  std::cout << std::endl << "Enter a line of text:" << std::endl;
  string text;
  std::getline(std::cin, text);             // Read a line into the string object

  Stack<const char> characters;             // A stack for characters

  for (int i {}; i < text.length(); ++i)
    characters.push(text[i]);               // Push the string characters onto the stack

  std::cout << std::endl;
  while(!characters.isEmpty())
    std::cout << characters.pop();          // Pop the characters off the stack

  std::cout << std::endl;
}

Result


Related Tutorials