Well i decided to code up an example of using template classes as i needed to code something out of will and also feel i need to code more c++, so here is my class and an implementation of it. I will look over it tomorrow when i am fresh and double check thigns to ensure its all correct as not to misguide people who happen to find this site.
anway first is the node class, this is a little object to hold a value of a certain type defined on initialisation of a Stack object and a pointer to the next node of the same type.
node.h
template <class T> class node { public: node<T>* next; T value; };
Next is the main class Stack and its implemented methods
- push
- pop
Figured those were the main ones i was intersted in at such a time, as those are the functions of a stack and one must remember the rules of last in first out, queues on the other hand work differently, first in first out i guess you could say, anyway here is the the class
Stack.h
#include "node.h" template <class T> class Stack { public: Stack(); ~Stack(); void push(T pNode); void printNodes(); void pop(); node<T>* getNode( int i ); private: node<T>* head; node<T>* current; }; template <class T> Stack<T>::Stack() { head = NULL; current = head; } template <class T> Stack<T>::~Stack() { current = head; node<T>* ptr; while ( current->next != NULL ) { ptr = current->next; delete(current); current = ptr; } delete(ptr); } template <class T> void Stack<T>::push(T pNode) { node<T> *p = new node<T>( ); p->next = NULL; p->value = pNode; if ( head == NULL ) { head = p; current = head; return; } current->next = p; current = p; } template <class T> void Stack<T>::printNodes() { node<T>* iterator = head; while ( iterator != NULL ) { cout << iterator->value << endl; iterator = iterator->next; } } template<class T> void Stack<T>::pop() { node<T>* tmp = head; node<T>* previous; if ( head == NULL ) return; // if there is nothing in the Stack return while (true) { if ( tmp->next == NULL ) { delete(tmp); previous->next = NULL; return; } previous = tmp; tmp = tmp->next; } } template <class T> node<T>* Stack<T>::getNode( int i ) { node<T>* tmp = head; // ptr to the node we want for ( int k = 0; k < i; k++ ) { if ( tmp->next == NULL ) return NULL; tmp = tmp->next; } return tmp; }
Finally the implementation of the class, just a few examples of how to declare and use the functions, showing the type char* and also int
Main.cpp
#include <iostream> #include "Stack.h" using namespace std; /* struct defining a basic person object */ struct person { char* pzName; int pzAge; }; int main() { cout << "This is a Stack Example, so remember that stacks work on\n" << "a last in first out basis, firstly we will do an int example\n" << "followed by a character string Stack\n\n" << endl; /** create a int type stack */ Stack<int> *p = new Stack<int>(); p->push( 2 ); p->push( 50 ); p->push( 24 ); p->push( 12 ); p->printNodes(); // print our nodes added cout << "Now We Pop A Node" << endl; p->pop(); p->printNodes(); cout << "Notice the Difference ? " << endl; p->~Stack(); // deconstructor /** create a character pointer type example Stack */ cout << "Now a char* stack example" << endl; Stack<char*> *str = new Stack<char*>(); str->push("testing"); str->push("stack"); str->push("example"); str->push("from"); str->push("thebbqcode"); str->printNodes(); cout << "Now ->pop()" << endl; p->pop(); str->printNodes(); str->~Stack(); // deconstructor cout << "End of char* example\n\nPerhaps a double example?" << endl; /** Stack of floats */ Stack<double> *flt = new Stack<double>(); flt->push(2.38); flt->push(2.44); flt->push(19.23); flt->printNodes(); cout << "Now we pop" << endl; flt->pop(); flt->printNodes(); cout << "End of float example " << endl; flt->~Stack(); /** Now how about we create a few random structs or objects and use the template class to store them, we will create a person object, the person will have a name and age and we will use a struct to model this object. The struct is defined at the top of this file */ cout << "Now or person struct object examples\n\n" << endl; Stack<person> *per = new Stack<person>(); person one, two, three; // create some people // person one one.pzName = "Robert"; one.pzAge = 25; // person two two.pzName = "Banga"; two.pzAge = 17; //person three three.pzName = "cougz"; three.pzAge = 28; // now push these persons onto the stack // //cout << "There are " << per->count << " nodes in the stack " << endl; per->push( one ); per->push( two ); per->push( three ); //cout << "There are " << per->count << " nodes in the stack " << endl; // now in order to print these values, we would need to overload ofstream // // so in this case we will just assume that we have done so and leave it // // at that, this is the reason it might be wise to include a function to // // return a node so we can reach values witin it for objects // // as such a sample is implemented to show this. // per->pop(); //cout << "There are " << per->count << " nodes in the stack " << endl; if ( per->getNode(1) != NULL ) { cout << "Name : " << per->getNode(1)->value.pzName << endl; cout << "Age : " << per->getNode(1)->value.pzAge << endl; } else cout << "no nodes found" << endl; per->getNode(10); per->~Stack(); getchar(); return 0; }
Please let me know if you see something wrong or have advice on imporing the code :)
