Listing 3: David Reed’s original stack class, modified to account for operator new throwing a bad_alloc exception instead of returning a zero

#ifndef STACK_H
#define STACK_H

template<class T>
class Stack 
{
    unsigned nelems;
    int top;
    T* v;
public:
    unsigned Size();
    void Push(T);
    T Pop();

    Stack();
    ~Stack();
    Stack( const Stack& );
    Stack& operator=(const Stack&);

    bool Consistent() const;
};

template<class T>
Stack<T>::Stack()
{
    top = -1;
    v = new T[nelems=10];
}

template<class T>
Stack<T>::Stack( const Stack<T>& s )
{
    v = new T[nelems = s.nelems];
    if( s.top > -1 ) {
        for(top = 0; top <= s.top; top++) {
            v[top] = s.v[top];
        }
        top--;
    }
}

template<class T>
Stack<T>::~Stack()
{
    delete[] v;
}

template<class T>
void Stack<T>::Push( T element )
{
    top++;
    if( top == nelems-1 ) {
        T* new_buffer = new T[nelems+=10];
        for( int i = 0; i < top; i++ ) {
            new_buffer[i] = v[i];
        }
        delete [] v;
        v = new_buffer;
    }
    v[top] = element;
}

template<class T>
T Stack<T>::Pop()
{
    if( top < 0 ) {
        throw "pop on empty stack";
    }
    return v[top--];
}

template<class T>
unsigned Stack<T>::Size()
{
    return top+1;
}

template<class T>
Stack<T>& 
Stack<T>::operator=( const Stack<T>& s )
{
    delete [] v;
    v = new T[nelems = s.nelems];
    if( s.top > -1 ) {
        for(top = 0; top <= s.top; top++) {
            v[top] = s.v[top];
        }
        top--;
    }
    return *this;
}

template<class T>
bool Stack<T>::Consistent() const
{
    // Weak check
    return (top < int(nelems)) 
           and (v != 0);
}

#endif // STACK_H

— End of Listing —