//18. Шаблони за класове: пример със Stack; параметри и наследственост; // приятелски функции; статични членове на клас. // // Fig. 11.2: tstack1.h // Stack class template. #ifndef TSTACK1_H #define TSTACK1_H template< class T > class Stack { public: Stack( int = 10 ); // default constructor (stack size 10) // destructor ~Stack() { delete [] stackPtr; } // end ~Stack destructor bool push( const T& ); // push an element onto the stack bool pop( T& ); // pop an element off the stack // determine whether Stack is empty bool isEmpty() const { return top == -1; } // end function isEmpty // determine whether Stack is full bool isFull() const { return top == size - 1; } // end function isFull private: int size; // # of elements in the stack int top; // location of the top element T *stackPtr; // pointer to the stack }; // end class Stack // constructor template< class T > Stack< T >::Stack( int s ) { size = s > 0 ? s : 10; top = -1; // Stack initially empty stackPtr = new T[ size ]; // allocate memory for elements } // end Stack constructor // push element onto stack; // if successful, return true; otherwise, return false template< class T > bool Stack< T >::push( const T &pushValue ) { if ( !isFull() ) { stackPtr[ ++top ] = pushValue; // place item on Stack return true; // push successful } // end if return false; // push unsuccessful } // end function push // pop element off stack; // if successful, return true; otherwise, return false template< class T > bool Stack< T >::pop( T &popValue ) { if ( !isEmpty() ) { popValue = stackPtr[ top-- ]; // remove item from Stack return true; // pop successful } // end if return false; // pop unsuccessful } // end function pop #endif /****/ // Fig. 11.3: fig11_03.cpp // Stack-class-template test program. #include using std::cout; using std::cin; using std::endl; #include "tstack1.h" // Stack class template definition int main() { Stack< double > doubleStack( 5 ); double doubleValue = 1.1; cout << "Pushing elements onto doubleStack\n"; while ( doubleStack.push( doubleValue ) ) { cout << doubleValue << ' '; doubleValue += 1.1; } // end while cout << "\nStack is full. Cannot push " << doubleValue << "\n\nPopping elements from doubleStack\n"; while ( doubleStack.pop( doubleValue ) ) cout << doubleValue << ' '; cout << "\nStack is empty. Cannot pop\n"; Stack< int > intStack; int intValue = 1; cout << "\nPushing elements onto intStack\n"; while ( intStack.push( intValue ) ) { cout << intValue << ' '; ++intValue; } // end while cout << "\nStack is full. Cannot push " << intValue << "\n\nPopping elements from intStack\n"; while ( intStack.pop( intValue ) ) cout << intValue << ' '; cout << "\nStack is empty. Cannot pop\n"; return 0; } // end main /****/ // Fig. 11.4: fig11_04.cpp // Stack class template test program. Function main uses a // function template to manipulate objects of type Stack< T >. #include using std::cout; using std::cin; using std::endl; #include "tstack1.h" // Stack class template definition // function template to manipulate Stack< T > template< class T > void testStack( Stack< T > &theStack, // reference to Stack< T > T value, // initial value to push T increment, // increment for subsequent values const char *stackName ) // name of the Stack < T > object { cout << "\nPushing elements onto " << stackName << '\n'; while ( theStack.push( value ) ) { cout << value << ' '; value += increment; } // end while cout << "\nStack is full. Cannot push " << value << "\n\nPopping elements from " << stackName << '\n'; while ( theStack.pop( value ) ) cout << value << ' '; cout << "\nStack is empty. Cannot pop\n"; } // end function testStack int main() { Stack< double > doubleStack( 5 ); Stack< int > intStack; testStack( doubleStack, 1.1, 1.1, "doubleStack" ); testStack( intStack, 1, 1, "intStack" ); return 0; } // end main