STL Stack
The Standard Template Library provides an implementation of a stack. The underlying implementation is based on the STL vector class, which is presented in Sections 1.5.5 and 6.1.4. In order to declare an object of type stack, it is necessary
to first include the definition file, which is called “stack.” As with the STL vector, the class stack is part of the std namespace, so it is necessary either to use “std::stack” or to provide a “using” statement. The stack class is templated with the class of the individual elements. For example, the code fragment below declares a stack of integers.
STL does not throw an exception if the user calls top() or pop() when the stack is empty, whereas our own implementation (below) does. Even though no exception is thrown, it may very likely result in your program aborting. Thus, it is up to the programmer to be sure that no such illegal accesses are attempted.
(For example, s is a vector of integers, and e is an integer.)
1 |
|
Example of stack operation: Given the operations, what does the stack look like
Note the difference between pop(), which does not return a value, and top(),
1 | Operations Output Stack Contents |
Note about the keyword **const
- Member functions size(), top() and empty() use the const keyword to tell the compiler that they do not modify anything
- top() returns a const reference to the top of the stack so that the object in the top can only be read, not written
- pop() does not return the object it removes. The user program needs to read the object using top() before removing it by calling pop()
Our Stack Interface (not STL stack, which throws no exception)
1 | template <typename E> |
Observe that the member functions size
, empty
, and top
are all declared to be const, which informs the compiler that they do not alter the contents of the stack.
- The member function top returns a constant reference to the top of the stack, which means that its value may be read but not written.
An error condition occurs when calling either of the functions pop or top on an empty stack.
- This is signaled by throwing an exception of type StackEmpty, which is defined in Code Fragment 5.2.
1 | // Exception thrown on performing top or pop of an empty stack. |
5.1.4 Array-Based Stack Implementation
- Since arrays start at index [0],
t
is initialized to -1. //t = - 1
is used to identify when stack is empty. - Likewise,
t + 1
is used to identify the number of elements in a stack.
C++ Implementation of a Stack
- To keep the code simple, we have omitted the standard housekeeping utilities, such as a destructor, an assignment operator, and a copy constructor. We leave their implementations as an exercise.
1 | template <typeName E> |
Default Arguements in Function Calls
- In the consturctor, the desire capacity of the stack is its only argument.
- If no arguement is given, the default value
DEF_CAPACITY
is used.- We use an enumeration to define this default capacity value. This is the simplest way of defining symbolic integer constants within a C++ class
ArrayStack(int cap = DEF_CAPACITY); // constructor from capacity
- We use an enumeration to define this default capacity value. This is the simplest way of defining symbolic integer constants within a C++ class
- If no arguement is given, the default value
1 | template <typename E> |
The instance A is a stack of integers of the default capacity (100). The instance B is a stack of character strings of capacity 10.
1 | ArrayStack<int> A; // A = [ ], size = 0 |
An application may need more space than this, in which case our stack implementation might “crash” if too many elements are pushed onto the stack
Fortunately, there are other implementations that do not impose an arbitrary size limitation. One such method is to use the STL stack class, which was introduced earlier in this chapter. The STL stack is also based on the STL vector class, and it offers the advantage that it is automatically expanded when the stack overflows its current storage limits. In practice, the STL stack would be the easiest and most practical way to implement an array-based stack. - In instances where we have a good estimate on the number of items needing to go in the stack, the array-based implementation is hard to beat from the perspective of speed and simplicity. Stacks serve a vital role in a number of computing applications, so it is helpful to have a fast stack ADT implementation, such as the simple array-based implementation.
span2 Function
1 | int spans2(int x[], n) { |