Node is already a templated function. I have changed Main.cpp and Stack.h to templated classes to the best of my abilities but it is not working for some reason. It compiles but says initially that the stack is full and something is wrong.
Main.cpp
#include <iostream>
using namespace std;
#include "Stack.h"
void stack_test();
int main() {
stack_test();
return 0;
}
void stack_test() {
// Instantiate S1 as an int and S2 as a string
Stack<int> s1;
Stack<string> s2;
// Stack empty test for both S1 and S2
if (s1.isEmpty()) {
cout << "s1 is empty at the beginning." << endl;
} else {
cout << "s1 must be empty. Something's wrong!" << endl;
}
if (s2.isEmpty()) {
cout << "s2 is empty at the beginning." << endl;
} else {
cout << "s2 must be empty. Something's wrong!" << endl;
}
// Fill S1 and S2 with five int and five strings respectively
for(int i = 0; i < 5; i++)
s1.push(1 * (i + 1));
string one = "1", two = "2", three = "3", four = "4", five = "5";
s2.push(one);
s2.push(two);
s2.push(three);
s2.push(four);
s2.push(five);
// pop() test: reverses the items
cout << "Expected Ints: 5 4 3 2 1 -->" << endl;
for (int i = 0; i < 5; i++) {
cout << s1.top() << endl;
s1.pop();
}
// Stack empty test
if (s1.isEmpty()) {
cout << "s1 is empty after five pop() calls." << endl;
} else {
cout << "s1 must be full. Something's wrong!" << endl;
}
if (s2.isEmpty()) {
cout << "s2 is empty after five pop() calls." << endl;
} else {
cout << "s2 must be full. Something's wrong!" << endl;
}
// StackEmptyException test
try {
cout << "One more pop when the stack is empty..." << endl;
s1.pop();
}
catch (Stack<int>::StackEmptyException) {
cout << "Exception: cannot pop, stack is empty" << endl;
}
try {
cout << "One more pop when the stack is empty..." << endl;
s2.pop();
}
catch (Stack<string>::StackEmptyException) {
cout << "Exception: cannot pop, stack is empty" << endl;
}
}
Node.h
#ifndef NODE_H
#define NODE_H
template <class T> class Node {
public:
T data;
Node<T>* next;
public:
Node(T);
virtual ~Node(); //for later use of polymorphismi, review the topic again
// friend class Stack; // allows dStack for private member access
};
// constructor: create a new Node with d as data
template <class T>
Node<T>::Node(T data) {
this->data = data;
next = 0;
}
template <class T>
Node<T>::~Node() {
}
#endif
Stack.h
#ifndef STACK_H
#define STACK_H
#include <cstdlib>
#include <iostream>
#include <new>
using namespace std;
#include "Node.h"
template <class T> class Stack {
private:
Node<T>* topNode;
public:
class StackEmptyException { };
Stack();
void push(T);
void pop();
bool isEmpty();
bool isFull();
double top();
virtual ~Stack();
};
// constructor: new stack is created. topNode is null.
template< class T>
Stack<T>::Stack() {
// topNode = 0;
}
// push a data onto the stack
template< class T>
void Stack<T>::push(T data) {
try {
Node<T>* newNode = new Node<T>(data);
newNode->next = topNode;
topNode = newNode;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// pop the data from the stack
template< class T>
void Stack<T>::pop() {
if (isEmpty())
throw StackEmptyException();
Node<T>* discard = topNode;
topNode = topNode->next;
delete discard;
}
// is stack empty?
template< class T>
bool Stack<T>::isEmpty() {
return (topNode == 0);
}
// is stack full?
template< class T>
bool Stack<T>::isFull() {
return false; // never, unless memory is full
}
// read the data on the top of the stack
template< class T>
double Stack<T>::top() {
if (isEmpty())
throw StackEmptyException();
return topNode->data;
}
// destructor: free all the memory allocated for the stack
template<class T>
Stack<T>::~Stack() {
while (!isEmpty())
pop();
}
#endif