Computer Science Canada

Implementing a template class Stack

Author:  simonsayz [ Sat Apr 11, 2009 1:17 pm ]
Post subject:  Implementing a template class Stack

I'm using Visual C++ 2008 Express Edition.
I'm getting the same three compile errors each time I compile this project. I don't know if my syntax for the template class is correct or not but I cannot figure it out. Any help or tips would be appreciated.
The three errors are:
stack.h(10) : error C2143: syntax error : missing ';' before '<'
stack.h(22) : see reference to class template instantiation 'Stack<ItemType>' being compiled (Warning)
stack.h(10) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
stack.h(10) : error C2238: unexpected token(s) preceding ';'
Now I know I will have A LOT of compile errors once these three errors are gone so don't worry about my function definitions. I haven't even had a chance to check if they are right or not.
Also the errors all seem to point to: NodeType<ItemType>* topPtr, for my private variable and the last "};" of my class.

c++:

#include<iostream>
#include<cstdlib>

using namespace std;

template<class ItemType>
class Stack
{
private:
        NodeType<ItemType>* topPtr;      // It points to a singly-linked list
public:
    Stack();                         // default constructor: Stack is created and empty
    Stack(const Stack<ItemType> &x); // copy constructor: implicitly called for a deep copy
    void MakeEmpty();             // Stack is made empty; you should deallocate all the nodes of the linked list
        bool IsEmpty();      // test if the stack is empty
        bool IsFull();           // test if the stack is full; assume MAXITEM=5
        ItemType length();                               // return the number of elements in the stack
        //void Print();      // print the value of all elements in the stack in the sequence from the top to bottom
        void Push(ItemType x);         // insert x onto the stack   
        void Pop(ItemType &x);           // delete the top element from the stack
    ~Stack();                   // Destructor:  memory for nodes needs to be deallocated
};

template<class ItemType>
struct NodeType
{
       ItemType info;
       NodeType* next;
};

template<class ItemType>
 Stack<ItemType>::Stack()
{
        topPtr = NULL;
}

template<class ItemType>
 Stack<ItemType>::Stack(const Stack<ItemType> &x)
{
        NodeType* ptr1;
    NodeType* ptr2;

    if(x.topPtr == NULL){
        topPtr == NULL;
    }else{
        topPtr = new NodeType;
        topPtr->info = x.topPtr->info;
        ptr1 = x.topPtr->next;
        ptr2 = topPtr;
        while(ptr1 != NULL)
        {
            ptr2->next = new NodeType;
            ptr2 = ptr2->next;
            ptr2->info = ptr1->info;
            ptr1 = ptr1->next;
        }
        ptr2->next = NULL;
    }
}

template<class ItemType>
void Stack<ItemType>::MakeEmpty()
{
        NodeType* tempPtr;

        while(topPtr != NULL)
        {
                tempPtr = topPtr;
                topPtr = topPtr->next;
                delete tempPtr;
        }
}

template<class ItemType>
bool Stack<ItemType>::IsEmpty()
{
        return (topPtr = NULL);
}

template<class ItemType>
bool Stack<ItemType>::IsFull()
{
        NodeType* location;
        try
        {
                location = new NodeType;
                delete location;
                return false;
        }
        catch(bad_alloc exception)
        {
                return true;
        }
}

template<class ItemType>
ItemType Stack<ItemType>::length()
{
        ItemType tempLength = 0;
        while(topPtr != NULL)
        {
                tempLength++;
        }
        return tempLength;
}

template<class ItemType>
void Stack<ItemType>::Pop(ItemType &x)
{
        if(IsEmpty())
                throw EmptyStack();
        else
        {
                NodeType* tempPtr;
                tempPtr = topPtr;
                topPtr = topPtr->next;
                delete tempPtr;
        }
}

template<class ItemType>
void Stack<ItemType>::Push(ItemType x)
{
        if(IsFull())
                throw FullStack();
        else
        {
                NodeType* location;
                location = new NodeType;
                location->info = x;
                location->next = topPtr;
                topPtr = location;
        }
}

template<class ItemType>
Stack<ItemType>::~Stack()
{
        MakeEmpty();
}


Author:  wtd [ Sat Apr 11, 2009 2:36 pm ]
Post subject:  RE:Implementing a template class Stack

While I don't think I have the energy for a deep analysis, try moving the declaration for the NodeType struct to above the declaration for the Stack class.

Stack shouldn't know what NodeType is until NodeType is declared.

Author:  simonsayz [ Sat Apr 11, 2009 3:17 pm ]
Post subject:  RE:Implementing a template class Stack

I tried that already and didn't work. I'm almost sure it has something to do with the template<class ItemType>. Thanks for the tip though. Any other quick tips would help.

Author:  bbi5291 [ Sat Apr 11, 2009 3:52 pm ]
Post subject:  Re: Implementing a template class Stack

I no longer have Visual Studio 2008, but I tried to compile your code on g++ and I conclude:

1. Yes, you have to put the NodeType declaration before the Stack declaration.
2. Whenever you use the name "NodeType" outside of the NodeType declaration itself, you have to include template arguments. For example,
code:

NodeType<ItemType>* ptr1;

not just
code:

NodeType* ptr1;

The compiler cannot be expected to guess that you want to use the template argument of some other class as the template argument to NodeType.
3. You can't name your exception "exception" (as in "catch(bad_alloc exception)") because exception is a type that has already been defined (in fact, bad_alloc inherits from it, I believe.)
4. EmptyStack and FullStack aren't declared... simply including the lines
code:

struct EmptyStack{};
struct FullStack{};

should fix this.

Also, I don't think it's strictly necessary but you should specify that the functions Pop and Push throw the exceptions that they do (I'm not sure if this is for readability reasons, or what):
code:

...
void Push(ItemType x) throw(FullStack);
void Pop(ItemType &x) throw(EmptyStack);
...
void Stack<ItemType>::Pop(ItemType &x) throw(EmptyStack)
{
...
}
...
void void Stack<ItemType>::Push(ItemType x) throw(FullStack)
{
...
}
...

Author:  simonsayz [ Sat Apr 11, 2009 4:29 pm ]
Post subject:  RE:Implementing a template class Stack

ah ha! Thanks bbi5291, I did include <ItemType> each time I declared NodeType* and also used a different method instead of using exceptions and those compile errors FINALLY disappeared. Thanks a ton. Will update my code when finished and error free.

Author:  simonsayz [ Sat Apr 11, 2009 5:28 pm ]
Post subject:  RE:Implementing a template class Stack

Alright I finally finished without any compile errors. Thanks bbi5291 and wtd for helping me out.

c++:
#ifndef STACK_H
#define STACK_H

#include<iostream>
#include<cstdlib>
#include<new>

using namespace std;

template<class ItemType>
struct NodeType
{
       ItemType info;
       NodeType* next;
};

template<class ItemType>
class Stack
{
private:
        NodeType<ItemType>* topPtr; // It points to a singly-linked list
        int size;
public:
    Stack();                         // default constructor: Stack is created and empty
    Stack(const Stack<ItemType> &x); // copy constructor: implicitly called for a deep copy
    void MakeEmpty();             // Stack is made empty; you should deallocate all the nodes of the linked list
        bool IsEmpty();      // test if the stack is empty
        bool IsFull();           // test if the stack is full; assume MAXITEM=5
        int length();                // return the number of elements in the stack
        void Print();                // print the value of all elements in the stack in the sequence from the top to bottom
        void Push(ItemType x);         // insert x onto the stack   
        void Pop(ItemType &x);       // delete the top element from the stack
        void Reset();
    ~Stack();                   // Destructor:  memory for nodes needs to be deallocated
};



template<class ItemType>
 Stack<ItemType>::Stack()
{
        topPtr = NULL;
        size = 0;
}

template<class ItemType>
 Stack<ItemType>::Stack(const Stack<ItemType> &x)
{
        NodeType<ItemType>* ptr1;
    NodeType<ItemType>* ptr2;

    if(x.topPtr == NULL){
        topPtr == NULL;
    }else{
        topPtr = new NodeType<ItemType>;
        topPtr->info = x.topPtr->info;
        ptr1 = x.topPtr->next;
        ptr2 = topPtr;
        while(ptr1 != NULL)
        {
            ptr2->next = new NodeType<ItemType>;
            ptr2 = ptr2->next;
            ptr2->info = ptr1->info;
            ptr1 = ptr1->next;
        }
        ptr2->next = NULL;
    }
}

template<class ItemType>
void Stack<ItemType>::MakeEmpty()
{
        NodeType<ItemType>* tempPtr;
        while(topPtr != NULL) {
        tempPtr = topPtr;
    topPtr = topPtr->next;
    delete tempPtr;
        }
}

template<class ItemType>
bool Stack<ItemType>::IsEmpty()
{
        return (topPtr = NULL);
}

template<class ItemType>
bool Stack<ItemType>::IsFull()
{
        NodeType<ItemType>* location;
        location = new NodeType<ItemType>;
        if(location == NULL)
         return true;
        else {
         delete location;
     return false;
        }
}

template<class ItemType>
int Stack<ItemType>::length()
{
        return size;
}

template<class ItemType>
void Stack<ItemType>::Print()
{
        Reset();
        while(topPtr != NULL)
                {
                        cout << topPtr -> info << endl;
                        topPtr = topPtr -> next; // Moving thought the list
                }
}

template<class ItemType>
void Stack<ItemType>::Pop(ItemType &x)
{
        NodeType<ItemType>* tempPtr;
        x = topPtr->info;
        tempPtr = topPtr;
        topPtr = topPtr->next;
        delete tempPtr;
        size--;
}

template<class ItemType>
void Stack<ItemType>::Push(ItemType x)
{
        NodeType<ItemType>* location;
        location = new NodeType<ItemType>;
        location->info = x;
        location->next = topPtr;
        topPtr = location;
        size++;
}

template<class ItemType>
void Stack<ItemType>::Reset()
{
        size = 0;
}

template<class ItemType>
Stack<ItemType>::~Stack()
{
        MakeEmpty();
}

#endif




Mod Edit: Fixed broken syntax tags.
code:
[syntax="cpp"]Code Here[/syntax]


: