Problem 1:
The C version of Stack defines: int element_type
But what if we wanted a stack of chars?
Or multiple stacks of different types? (polymorphism)
Solution: C++
Problem 2:
The C version is not a very good ADT: does not hide variables
Solution: C++
Problem 3:
C pointers are bad.
Solution: C++?
Problem 4:
C syntax is not bad enough.
Solution: C++
Stacks: stack3 [29]
% g++ -o stack3 stack3.cc >tcc stack3.cpp % stack3 5 5.5 a b Empty stack % stack4 // solution program 5 5.5 a b b
Stacks: stack3.h [30]
static const Default_Size = 100;
template <class Element_Type>
class Stack {
private:
unsigned int Full_Stack;
int Top_Of_Stack;
Element_Type *Stack_Array;
Stack( const Stack & Value);
public:
Stack( unsigned int Max_Size = Default_Size ); // Constructor
~Stack( ) { delete [ ] Stack_Array; } // Destructor
const Stack & operator = ( const Stack & Value ); // Overloaded Operator
void operator -- ( ); // Overloaded Operator
// Member functions
void Push( const Element_Type & X );
void Pop ( );
Element_Type Pop_And_Top( );
Element_Type Top( ) const;
void Make_Empty( );
int Is_Empty( ) const { return Top_Of_Stack == -1; }
int Is_Full ( ) const { return Top_Of_Stack == Full_Stack - 1; }
};
Stacks: stack3.cc [31]
#include <iostream.h>
#include "stack3.h"
template <class Element_Type>
Stack<Element_Type>::
Stack( unsigned int Max_Size ) {
Full_Stack = Max_Size;
Top_Of_Stack = -1;
Stack_Array = new Element_Type[ Max_Size ];
if( Stack_Array == NULL )
cout << "Out of space!" << endl;
}
template <class Element_Type>
inline void
Stack<Element_Type>::
Push( const Element_Type & X ) {
if( Is_Full( ) ) cout << "Stack is full" << endl;
else Stack_Array[++Top_Of_Stack] = X;
}
template <class Element_Type>
inline Element_Type
Stack<Element_Type>::
Top( ) const {
if( Is_Empty( ) ) cout << "Empty stack" << endl;
else return Stack_Array[ Top_Of_Stack ];
}
template <class Element_Type> void
Stack<Element_Type>:: operator -- ( ) {
if( !Is_Empty( ) ) --Top_Of_Stack;
}
template <class Element_Type> const Stack<Element_Type> &
Stack<Element_Type>:: operator = ( const Stack<Element_Type> & Value ) {
Top_Of_Stack = -1; // versus Value.Top_Of_Stack
// worry about max size, not type conflict
return *this
}
main ( ) {
Stack<int> S; // create a stack of integers
Stack<double> S1(10); // specify the maximum size
Stack<char> S2, S3; // two stacks of char
S.Push(3); S.Push(5);
cout << S.Top( ) << endl; // output 5
S1.Push(3.3); S1.Push(5.5);
cout << S1.Top( ) << endl; // output 5.5
S2.Push('b'); S2.Push('a');
cout << S2.Top( ) << endl; // output a
--S2; // use operator to pop
cout << S2.Top( ) << endl; // output b
S3 = S2; // use operator to assign
cout << S3.Top( ) << endl; // output b
}