//---------------------------------------------------------------- // // dynamic-stack.cpp // // Implements a simple character stack, using dynamic memory // management. As each element is pushed or popped, this version // allocates or deallocates space. // // A heavily modified version of the example from Pohl, // C++ by Dissection, pages 218-223. // // written by: Simon Parsons // modified : 21st April 2009 // #include #include using namespace std; //---------------------------------------------------------------- // // stackElement // // A classic component of a dynamic datastructure, this holds a // data element, in this case a character, and pointer to such an // object. class stackElement { private: char contents; stackElement *link; public: void setContents(char); char getContents(void); void setLink(stackElement *); stackElement * getLink(void); }; void stackElement::setContents(char c){ contents = c; } char stackElement::getContents(void){ return contents; } void stackElement::setLink(stackElement * link){ this->link = link; } stackElement * stackElement::getLink(void){ return link; } //---------------------------------------------------------------- // // charStack // // Each element of the stack is a stackElement. The only datamember // that the stack structure contains is a pointer to the current top // of the stack. class charStack { private: stackElement *topElement; public: charStack(); // constructor charStack( const charStack& stk ); // copy constructor ~charStack(); // destructor void reset(); void push(char); char pop(); char topOfStack() const; bool isEmpty() const; }; // constructor // // Set up the stack with a single stackElement in it, an element that // contains the null value \0. We do this to consciously mimic the way // that C++ handles strings. We could equally have the last element in // the stack have a NULL link. charStack::charStack() { topElement = new stackElement; topElement->setContents('\0'); topElement->setLink(NULL); } // copy constructor // // The job of the copy constructor is to set up a copy of whatever stack is // being copied --- we call the thing we are copying stk. charStack::charStack( const charStack& stk ){ charStack tmpStack; stackElement *linker; char c; // Start by creating a null element and putting it on the top of the // copy. topElement = new stackElement; topElement->setContents('\0'); topElement->setLink(NULL); // Now, take each element in stk, and put it into a temporary stack. linker = stk.topElement; while(linker->getContents()!='\0'){ tmpStack.push(linker->getContents()); linker = linker->getLink(); } // Now pop each element from the temporary stack and push it into the // copy (we need to use the temporary stack so that the elements are in // the right order). while(!tmpStack.isEmpty()){ c = tmpStack.pop(); push(c); } } // destructor // // Delete the storage that was allocated for the stack. First we reset the // stack (which deletes every stackElement except the null element), then // delete the null element which will be at the top of the stack. charStack::~charStack(){ reset(); delete topElement; } // reset // // Reset the stack by silently popping everything out of it until it // is empty. void charStack::reset(){ while(!isEmpty()) { pop(); } } // push // // To push an element onto the stack, we have to create a new element, // set is contents to that being pushed, and set its link to point to // the element that used to be on the top of the stack. void charStack::push(char c) { stackElement *p; p = topElement; topElement = new stackElement; topElement->setContents(c); topElement->setLink(p); } // pop // // To pop an element off the stack, we have to remember the value in the // element, make topElement point to the next item in the stack, and then // free up memory by deleting the element. char charStack::pop() { char c; stackElement *p; p = topElement; c = topOfStack(); topElement = topElement->getLink(); delete p; return c; } // topOfStack // // Return the value at the top of the stack without removing it from the // stack. char charStack::topOfStack() const { return topElement->getContents(); } // isEmpty // // The stack is empty if the only element in it is the null element bool charStack::isEmpty() const { if(topOfStack() == '\0'){ return true; } else { return false; } } //---------------------------------------------------------------- // // Main program // Creates a stack, pushing a string into it, character by character // and then popping them out, reversing the string. int main() { charStack s; string str = "hello world"; int i = 0; cout << "string = " << str << endl; s.reset(); for(i=0; i < str.size(); i++) { s.push(str[i]); } cout << "invoke copy constructor" << endl; charStack r = s; cout << "reversed string= "; while (! s.isEmpty() ) { cout << s.pop(); } cout << endl; cout << "copied string= "; while (! r.isEmpty() ) { cout << r.pop(); } cout << endl; }